浏览 3914 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (3)
|
|
---|---|
作者 | 正文 |
发表时间:2012-03-22
//饿汉式 是线程安全的*/ class Single { private static final Single s = new Single(); private Single(){ } public static Single getInstance(){ return s; } } //懒汉式 有线程安全问题 //懒汉式可以实现延迟加载 //但是在多线程并发访问的情况下会出现安全问题 //可以通过加同步来解决,只是加上同步效率会稍低,这时候可以再使用双重判断来解决这个低效的问题 //加同步的时候使用的锁是 该类所属的字节码文件对象 class Single { private static Single s = null; private Single(){ } public static Single getInstance(){ if(s == null){ synchronized(Single.class){ if(s == null){ s = new Single(); } } } return s; } } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2012-03-22
最后修改:2012-03-22
这几天单例肿么这么火?
前面的s并没有声明为volatile 那么,现有两个线程同时调用getInstance,a先判断为null,于是去new了一个,问题在于赋值给instance之后,b线程不一定能见到这个值,b判断s==null的时候可能还是true,于是又去new了一个 另外,s=new Single();是分为好几步操作的: 0: new #2; //Single 1: dup 2: invokespecial #3; //Method Single."<init>":()V 3: astore_1 在非volatile情况下,有没有可能被reorder成下面这样呢: 0: new #2; //SingltonThread 1: dup 3: astore_1 2: invokespecial #3; //Method Single."<init>":()V 即,内存已经分配了,还没有调用构造函数,但s已经被赋值了,也不一定对其他线程可见,如果可见,第二个线程立马就拿s去用,这时候s实例尚未完全构建好,使用的时候是否可能会出问题呢 jdk1.4及之前,不能保证volatile变量不参与reorder,所以,1.4下双重加锁检查仍有问题 |
|
返回顶楼 | |