V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
OpooPages
V2EX  ›  Java

复习了一遍 Singleton 的 5 种写法

  •  
  •   OpooPages ·
    opoo · 2015-07-16 15:41:31 +08:00 · 3810 次点击
    这是一个创建于 3426 天前的主题,其中的信息可能已经有所发展或是发生改变。

    https://gist.github.com/opoo/e48dbc0b3c5d0afddfc0

    好吧,github gist 貌似暂时不能访问了,贴在下面。

    public class SingletonDemo {
        public static class Singleton1{
            private static final Singleton1 instance = new Singleton1();
            private Singleton1(){}
            public static Singleton1 getInstance(){
                return instance;
            }
        }
    
        public static class Singleton2{
            private static Singleton2 instance;
            private Singleton2(){};
            public static synchronized Singleton2 getInstance(){
                if(instance == null){
                    instance = new Singleton2();
                }
                return instance;
            }
        }
    
        public static class Singleton3{
            private static volatile Singleton3 instance;
            private Singleton3(){}
            public static Singleton3 getInstance(){
                if(instance == null){
                    synchronized (Singleton3.class){
                        if(instance == null){
                            instance = new Singleton3();
                        }
                    }
                }
                return instance;
            }
        }
    
        public static class Singleton4{
            private static final Singleton4 instance;
            static{
                instance = new Singleton4();
            }
            private Singleton4(){}
            public static Singleton4 getInstance(){
                return instance;
            }
        }
    
        public static class Singleton5{
            private static class SingletonHolder{
                private static final Singleton5 instance = new Singleton5();
            }
            private Singleton5(){}
            public static Singleton5 getInstance(){
                return SingletonHolder.instance;
            }
        }
    }
    
    17 条回复    2015-08-31 19:44:27 +08:00
    cikelengfeng
        1
    cikelengfeng  
       2015-07-16 17:22:59 +08:00
    hey boy:

    public enum MySingleton {
    INSTANCE;
    }
    yxaaa123
        2
    yxaaa123  
       2015-07-16 18:14:46 +08:00
    比孔乙己知道得多
    delavior
        3
    delavior  
       2015-07-16 18:40:39 +08:00
    茴字有四种写法,你知道吗
    slixurd
        4
    slixurd  
       2015-07-16 18:45:45 +08:00
    没有Enum版,差评
    感觉只要知道一个double-check Locking版本,一个enum就够了。
    FrankFang128
        5
    FrankFang128  
       2015-07-16 18:57:46 +08:00 via Android
    var s = {}
    成功
    anohana
        6
    anohana  
       2015-07-16 18:59:41 +08:00 via iPhone
    都是非线程安全的
    OpooPages
        7
    OpooPages  
    OP
       2015-07-16 19:32:15 +08:00
    @cikelengfeng
    @slixurd
    好吧,enum方式也挺好。

    个人比较喜欢 double-checked locking和 SingletonHolder 的。

    @anohana 好像是线程安全的吧,不然要什么 synchronized、volatile干啥。
    zddhub
        8
    zddhub  
       2015-07-16 19:52:21 +08:00 via iPhone
    当年面试,问我怎么继承单例,直接懵逼了。
    OpooPages
        9
    OpooPages  
    OP
       2015-07-16 19:54:58 +08:00 via Android
    @zddhub 求指教,我也不知道怎么继承单例。
    hitsmaxft
        10
    hitsmaxft  
       2015-07-16 21:51:32 +08:00
    @anohana 最后一个是依赖 classloader 实现, 所以是线程安全的。
    aliuwr
        11
    aliuwr  
       2015-07-16 22:16:13 +08:00
    @hitsmaxft 4 和 5 相比有什么区别?
    swolf119
        12
    swolf119  
       2015-07-16 22:28:58 +08:00
    嘻嘻,反射调你私构函数,让你单!
    evilgod528
        13
    evilgod528  
       2015-07-16 22:30:31 +08:00
    需要记那么多吗?记住 double-check Locking 还有 enum 就行了吧
    hitsmaxft
        14
    hitsmaxft  
       2015-07-16 22:35:02 +08:00 via iPhone   ❤️ 1
    @aliuwr 没啥区别,就是innerclass理论上可以到getinstance调用时实例化,而不是利用static实例化。

    但是,服务器一般希望启动时全部依赖初始化完毕,否者运行到这里才挂起去加载类,鬼知道哪天就出问题了。。
    bgcolor0325
        15
    bgcolor0325  
       2015-07-17 16:39:16 +08:00
    线程不安全啊
    caixiexin
        16
    caixiexin  
       2015-07-23 12:20:10 +08:00
    说来惭愧,最近也才知道enum这种简单安全的写法。。
    tchekai704
        17
    tchekai704  
       2015-08-31 19:44:27 +08:00
    double-checked locking 似乎和 wiki 上的不一样吧
    https://en.wikipedia.org/wiki/Double-checked_locking#Usage_in_Java
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2724 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 09:25 · PVG 17:25 · LAX 01:25 · JFK 04:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.