锁定老帖子 主题:java关于单例模式的一些疑问?
该帖已经被评为新手帖
|
|
---|---|
作者 | 正文 |
发表时间:2009-04-22
最后修改:2009-04-22
引用 单例首要的条件就是线程安全,所以不会有线程公享资源的事情,何来资源一说?要是有资源公享的话,那还是单例吗?
是的,但我的理解“共享”是“所有线程共享了进程的资源”,而这里的单例实例就是其中的一部分。 而“共享”并非“同时使用”吧~ 就像那位兄台说的“厕所” 所以为了解决“同时使用”带来的问题,就得做好“线程安全”了。 |
|
返回顶楼 | |
发表时间:2009-04-23
构造方法私,是防止在其他类中new对象,但你的属性是static的,所以即使在其他类中new了n个对象,但他们的属性是共享的,所以要考虑安全问题,你可以加个类锁,这样数据就安全了,所以私有的构造方法不是必须的,
|
|
返回顶楼 | |
发表时间:2009-04-24
longrui 写道 chenhua_1984 写道 1构造函数有什么样的要求?
2这里的线程安全问题是怎么回事? 1.私有构造行数是禁止通过实例该类获得对象,如: new Test().getInstence(); 2.线程安全是指如果有多个线程,在第一个线程还没有执行到new Test()的时候,第二个线程调用该方法时判断test仍然为null,所以仍然会执行new Test()。 所以一般使用synchronized关键字将该方法声明成同步方法,如: public static synchronized Test getInstence 线程安全是指多个线程访问一个资源时(这里指对象),不会发生冲突,保证同一时间只有一个线程访问该资源。 单例中的类只实例化一次,new Test()不会多次执行,每次线程访问时得到同一个实例。这里说的有点问题。 |
|
返回顶楼 | |
发表时间:2009-04-24
sunnymoon 写道 longrui 写道 chenhua_1984 写道 1构造函数有什么样的要求?
2这里的线程安全问题是怎么回事? 1.私有构造行数是禁止通过实例该类获得对象,如: new Test().getInstence(); 2.线程安全是指如果有多个线程,在第一个线程还没有执行到new Test()的时候,第二个线程调用该方法时判断test仍然为null,所以仍然会执行new Test()。 所以一般使用synchronized关键字将该方法声明成同步方法,如: public static synchronized Test getInstence 线程安全是指多个线程访问一个资源时(这里指对象),不会发生冲突,保证同一时间只有一个线程访问该资源。 单例中的类只实例化一次,new Test()不会多次执行,每次线程访问时得到同一个实例。这里说的有点问题。 多个线程同时操作一个单例,不就不安全了吗??? |
|
返回顶楼 | |
发表时间:2009-04-24
有人根据创建的时间把单例模式分为懒汉式和饿汉式
懒汉式是指在调用的时候才创建,就像你前面的代码所做的,优点是只有用到了才会占用资源 饿汉式是在初始化就创建了这个对象,优点是预先加载,在调用时省去了创建(还有可能加载配置数据)的时间 |
|
返回顶楼 | |
发表时间:2009-04-24
youthon 写道 有人根据创建的时间把单例模式分为懒汉式和饿汉式 懒汉式是指在调用的时候才创建,就像你前面的代码所做的,优点是只有用到了才会占用资源 饿汉式是在初始化就创建了这个对象,优点是预先加载,在调用时省去了创建(还有可能加载配置数据)的时间 饿汉式:在类加载时static{}.静态块中 |
|
返回顶楼 | |
发表时间:2009-04-25
kulinglei 写道 sunnymoon 写道 longrui 写道 chenhua_1984 写道 1构造函数有什么样的要求?
2这里的线程安全问题是怎么回事? 1.私有构造行数是禁止通过实例该类获得对象,如: new Test().getInstence(); 2.线程安全是指如果有多个线程,在第一个线程还没有执行到new Test()的时候,第二个线程调用该方法时判断test仍然为null,所以仍然会执行new Test()。 所以一般使用synchronized关键字将该方法声明成同步方法,如: public static synchronized Test getInstence 线程安全是指多个线程访问一个资源时(这里指对象),不会发生冲突,保证同一时间只有一个线程访问该资源。 单例中的类只实例化一次,new Test()不会多次执行,每次线程访问时得到同一个实例。这里说的有点问题。 多个线程同时操作一个单例,不就不安全了吗??? no |
|
返回顶楼 | |
发表时间:2009-04-27
一般Singleton模式通常有几种形式:
public class Singleton { private Singleton(){} //在自己内部定义自己一个实例,是不是很奇怪? //注意这是private 只供内部调用 private static Singleton instance = new Singleton(); //这里提供了一个供外部访问本class的静态方法,可以直接访问 public static Singleton getInstance() { return instance; } } 第二种形式: public class Singleton { private static Singleton instance = null; public static synchronized Singleton getInstance() { if (instance==null) instance=new Singleton(); return instance; } } 使用Singleton.getInstance()可以访问单态类。 上面第二中形式是lazy initialization,也就是说第一次调用时初始Singleton,以后就不用再生成了。 注意到lazy initialization形式中的synchronized,这个synchronized很重要,如果没有synchronized,那么使用getInstance()是有可能得到多个Singleton实例。关于lazy initialization的Singleton有很多涉及double-checked locking (DCL)的讨论,有兴趣者进一步研究。 一般认为第一种形式要更加安全些。 |
|
返回顶楼 | |
发表时间:2009-04-27
lkjust08 写道 一般Singleton模式通常有几种形式:
public class Singleton { private Singleton(){} //在自己内部定义自己一个实例,是不是很奇怪? //注意这是private 只供内部调用 private static Singleton instance = new Singleton(); //这里提供了一个供外部访问本class的静态方法,可以直接访问 public static Singleton getInstance() { return instance; } } 第二种形式: public class Singleton { private static Singleton instance = null; public static synchronized Singleton getInstance() { if (instance==null) instance=new Singleton(); return instance; } } 使用Singleton.getInstance()可以访问单态类。 上面第二中形式是lazy initialization,也就是说第一次调用时初始Singleton,以后就不用再生成了。 注意到lazy initialization形式中的synchronized,这个synchronized很重要,如果没有synchronized,那么使用getInstance()是有可能得到多个Singleton实例。关于lazy initialization的Singleton有很多涉及double-checked locking (DCL)的讨论,有兴趣者进一步研究。 一般认为第一种形式要更加安全些。 多谢!明白了 |
|
返回顶楼 | |
发表时间:2009-04-28
最后修改:2009-04-28
C_J 写道 tangshd 写道 本来不想注册 写道 Constructor的用法 和 static 的用法,如果不熟悉,可以用单例模式来加深对他们的理解。
单例模式的写法有很多吧,最简洁的才是最好的。 一个实例,虽然节约资源,缺点应该也很明显。就好比,厕所小便槽就一个,大家要排队等候。 兄台,您这个比喻好像不对吧..单例又不是单线程! [b]所有线程都共享一个资源 一个线程共享所有资源[/b] 要是“资源”是马桶,排队的就是“线程”。 兄台为什么认为那位兄台比喻不对呢?? 我同意 "所有线程都共享一个资源"这个观点, 我不认可的是 拿到"单例对象"后的其他操作的时候,不应该是排队等待,应该是竞争,当然这个操作是在没有加锁的情况下. |
|
返回顶楼 | |