来看看这个单例模式呗 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
Registering
V2EX    程序员

来看看这个单例模式呗

  •  
  •   Registering 2015 年 5 月 25 日 4742 次点击
    这是一个创建于 3884 天前的主题,其中的信息可能已经有所发展或是发生改变。

    看到EventBus和Universay image loader的代码中,单例模式都这样写-----两次判断是否为空
    平时我的习惯是只判断一次。

    看有些博客说,这样可以防止并发问题,而且提高效率,,,不大理解

    public static EventBus getDefault() { if (defaultInstance == null) { synchronized (EventBus.class) { if (defaultInstance == null) { defaultInstance = new EventBus(); } } } return defaultInstance; } 
    第 1 条附言    2015 年 5 月 26 日
    第一次验证
    是为了避免每次都加锁

    第二次验证
    当你有10个线程同时执行完第一步验证,其中一个线程拿到锁,如果没有第二步验证,则该线程直接创建对象。然后其他线程依次获得锁(依然没有第二步验证),其他线程都各自创建对象。这就出现了同步问题,违背了单例
    20 条回复    2015-06-01 09:36:22 +08:00
    bengol
        1
    bengol  
       2015 年 5 月 25 日   1
    Septembers
        2
    Septembers  
       2015 年 5 月 25 日 via Android
    如果高度强调并发性能那就需要考虑无锁实现了
    jadetang
        3
    jadetang  
       2015 年 5 月 25 日
    effective 第三条
    用私有构造器或者枚举类型强化单例属性。
    shiznet
        4
    shiznet  
       2015 年 5 月 25 日
    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>
    crazyxin1988
        5
    crazyxin1988  
       2015 年 5 月 25 日
    想理解这个问题,推荐你看 深入理解Java虚拟机 这本书
    大部分的博客也是抄来抄去 说不清原理
    pandorla1984
        6
    pandorla1984  
       2015 年 5 月 25 日   1
    简单地说就是你检查null之后lock之前可能那个值已经发生了改变,不是null了 (另一个线程对其进行了修改)。所以lock之后要再检查一次是否是null。
    dullwit
        7
    dullwit  
       2015 年 5 月 25 日   2
    Rocko
        8
    Rocko  
       2015 年 5 月 25 日 via Android   1
    简单说就是在安全地初始化实例后,以后每次拿实例就不用经过锁了。
    zhchaos
        9
    zhchaos  
       2015 年 5 月 25 日
    用枚举类型去实现单例吧,最简单,还不会有问题
    bigredapple
        10
    bigredapple  
       2015 年 5 月 25 日
    double check
    luman
        11
    luman  
       2015 年 5 月 25 日
    只判断一次会出现重复赋值的现象
    miao1007
        12
    miao1007  
       2015 年 5 月 25 日
    双重检验,第一次检验不用担心同步锁降低的效率,第二次检验可以去掉线程同步问题。不要用枚举,现在Android开发都是JDK7了。
    anerevol
        13
    anerevol  
       2015 年 5 月 25 日
    话说objective-C,在我不知道dispatch_once之前我也一直这么写的。
    Registering
        14
    Registering  
    OP
       2015 年 5 月 25 日
    @crazyxin1988
    有这本书(作者周志明),选择性的看了一部分而已,还没看到这个问题相关的章节,,,
    记得在哪一章吗?今晚我翻阅一下
    crazyxin1988
        15
    crazyxin1988  
       2015 年 5 月 25 日
    @Registering
    12章 java内存模型与线程
    里面重点讲volatile
    双锁检测只是提到
    617019296
        16
    617019296  
       2015 年 5 月 26 日 via Android
    @pandorla1984 这不敢苟同,,那你直接锁不就行了,,何必先检查再锁。。。
    Registering
        17
    Registering  
    OP
       2015 年 5 月 26 日
    @617019296

    第一次验证是为了避免每次都加锁
    第二次验证
    当你有10个线程同时执行完第一步验证,其中一个线程拿到锁,如果没有第二步验证,则该线程直接创建对象。然后其他线程依次获得锁(依然没有第二步验证),其他线程都各自创建对象。这就出现了同步问题,违背了单例
    Chrisplus
        18
    Chrisplus  
       2015 年 5 月 26 日
    @Registering 说的很清楚,谢谢
    wallacedong
        19
    wallacedong  
       2015 年 5 月 26 日
    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;
    }
    }
    pandorla1984
        20
    pandorla1984  
       2015 年 6 月 1 日
    @617019296 那岂不是每次都要锁。。。效率较低
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2757 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 15:00 PVG 23:00 LAX 07:00 JFK 10:00
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86