美文网首页
单利的三种写法

单利的三种写法

作者: MDZZ灭顶之灾12138 | 来源:发表于2018-09-22 18:16 被阅读23次

    double-check线程安全,适用于高并发。

    public class DoubleCheck{
            private volatile static  DoubleCheck ins;
            private DoubleCheck(){}
            public static DoubleCheck getIns() {
                if (null == ins) {
                    synchronized (DoubleCheck.class) {
                        if (null == ins) {
                            ins = new DoubleCheck();
                        }
                    }
                }
                return ins;
            }
        }
    

    执行ins = new DoubleCheck():

    1. 给ins分配内存
    2. 调用构造函数来初始化成员变量(可能会很久)
    3. 将ins对象指向分配的内存空间(执行完这一步,ins才不为空)
      以上的操作不是原子操作,jvm也可能重新排序指令,导致2,3步顺序可能会被打乱,,当第3步先于第2步完成,就会导致有的线程拿到了初始化未完毕的ins,就会出错。可以利用volatile禁止指令重新排序优化特性来解决。

    饿汉式:

    public class Early{
        private Early(){}
        private static final Early ins = new Early();
        public static Early getIns() {
            return ins;
        }
    

    内部类方式,比饿汉式更优秀,Effective Java 推荐

    public class Singleton{
            private Singleton(){}
            private static class Holder {
                private static final Singleton ins = new Singleton();
            }
            public static Singleton getIns() {
                return Holder.ins;
            }
        }
    

    经典模式:

    public class Singleton{
        private static Singleton ins;
        private Singleton(){}
        public static synchronized Singleton getIns() {
            if (null == ins) {
                ins = new Singleton();
            }
            return ins;
        }
    }
    

    延迟实例化,节省资源。但是synchronized,每次调用getIns()都得同步,很消耗性能。只需在第一次执行的时候同步,当ins实例化之后就不需要同步了。

    相关文章

      网友评论

          本文标题:单利的三种写法

          本文链接:https://www.haomeiwen.com/subject/atqwnftx.html