看到EventBus和Universay image loader的代码中,单例模式都这样写-----两次判断是否为空
平时我的习惯是只判断一次。
看有些博客说,这样可以防止并发问题,而且提高效率,,,不大理解
public static EventBus getDefault() {
if (defaultInstance == null) {
synchronized (EventBus.class) {
if (defaultInstance == null) {
defaultInstance = new EventBus();
}
}
}
return defaultInstance;
}
1
bengol May 25, 2015 |
2
Septembers May 25, 2015 via Android
如果高度强调并发性能那就需要考虑无锁实现了
|
3
jadetang May 25, 2015
effective 第三条
用私有构造器或者枚举类型强化单例属性。 |
4
shiznet May 25, 2015
Java如果是1.4及以前的版本,需要注意下这个:
http://zh.wikipedia.org/wiki/%E5%8F%8C%E9%87%8D%E6%A3%80%E6%9F%A5%E9%94%81%E5%AE%9A%E6%A8%A1%E5%BC%8F <quote> 在J2SE 1.4或更早的版本中使用双重检查锁有潜在的危险,有时会正常工作:区分正确实现和有小问题的实现是很困难的。取决于编译器,线程的调度和其他并发系统活动,不正确的实现双重检查锁导致的异常结果可能会间歇性出现。重现异常是十分困难的。 </quote> |
5
crazyxin1988 May 25, 2015
想理解这个问题,推荐你看 深入理解Java虚拟机 这本书
大部分的博客也是抄来抄去 说不清原理 |
6
pandorla1984 May 25, 2015 简单地说就是你检查null之后lock之前可能那个值已经发生了改变,不是null了 (另一个线程对其进行了修改)。所以lock之后要再检查一次是否是null。
|
7
dullwit May 25, 2015 |
8
Rocko May 25, 2015 via Android 简单说就是在安全地初始化实例后,以后每次拿实例就不用经过锁了。
|
9
zhchaos May 25, 2015
用枚举类型去实现单例吧,最简单,还不会有问题
|
10
bigredapple May 25, 2015
double check
|
11
luman May 25, 2015
只判断一次会出现重复赋值的现象
|
12
miao1007 May 25, 2015
双重检验,第一次检验不用担心同步锁降低的效率,第二次检验可以去掉线程同步问题。不要用枚举,现在Android开发都是JDK7了。
|
13
anerevol May 25, 2015
话说objective-C,在我不知道dispatch_once之前我也一直这么写的。
|
14
Registering OP |
15
crazyxin1988 May 25, 2015
|
16
617019296 May 26, 2015 via Android
@pandorla1984 这不敢苟同,,那你直接锁不就行了,,何必先检查再锁。。。
|
17
Registering OP @617019296
第一次验证是为了避免每次都加锁 第二次验证 当你有10个线程同时执行完第一步验证,其中一个线程拿到锁,如果没有第二步验证,则该线程直接创建对象。然后其他线程依次获得锁(依然没有第二步验证),其他线程都各自创建对象。这就出现了同步问题,违背了单例 |
18
Chrisplus May 26, 2015
@Registering 说的很清楚,谢谢
|
19
wallacedong May 26, 2015
public class Singleton {
// Private constructor prevents instantiation from other classes private Singleton() { } /** * SingletonHolder is loaded on the first execution of Singleton.getInstance() * or the first access to SingletonHolder.INSTANCE, not before. */ private static class SingletonHolder { public static final Singleton INSTANCE = new Singleton(); } public static Singleton getInstance() { return SingletonHolder.INSTANCE; } } |
20
pandorla1984 Jun 1, 2015
@617019296 那岂不是每次都要锁。。。效率较低
|