黑马程序员技术交流社区

标题: 懒汉单例模式,个人总结。 [打印本页]

作者: kamo    时间: 2015-10-18 18:30
标题: 懒汉单例模式,个人总结。
   这个比较短,我就贴下代码,这都是个人,从网上搜搜,思考,总结的,
需要有一点基础的,想全面点了解的可以看看。
   希望能对大家有帮助。
/*
* 懒汉式单例
* 类进内存对象还没有存在,只有调用方法时才建立对象
*对象是方法被调用时才初始化,也叫做对象的延时加载
*它是线程不安全的,并发环境下很可能出现多个Singleton实例
*
*/
public class Singleton1 {

        /* 持有私有静态实例,防止被引用,此处赋值为null,目的是实现延迟加载 */
        private static Singleton1 instance = null;

        /* 私有构造方法,防止被实例化 */
        private Singleton1() {
        }

        /* 静态工程方法,创建实例 */
        // 多线程不安全
        /*
         * public static Singleton1 getInstance(){ if (instance == null){ instance =
         * new Singleton1(); } return instance; }
         */
        // 解决方案一:
        /*
         * 但是,synchronized关键字锁住的是这个对象,这样的用法,在性能上会有所下降, 因为每次调用getInstance(),都要对对象上锁,
         * 事实上,只有在第一次创建对象的时候需要加锁,之后就不需要了
         */
        /*
         * public static synchronized Singleton1 getInstance(){ if (instance ==
         * null){ instance = new Singleton1(); } return instance; }
         */
        // 解决方案二:
        /*
         * 将synchronized关键字加在了内部,也就是说当调用的时候是不需要加锁的,
         * 只有在instance为null,并创建对象的时候才需要加锁,性能有一定的提升
         *
         * 但是,这样的情况,还是有可能有问题的,看下面的情况:
         * 在Java指令中创建对象和赋值操作是分开进行的,也就是说instance = new Singleton();
         * 语句是分两步执行的。但是JVM并不保证这两个操作的先后顺序,
         * 也就是说有可能JVM会为新的Singleton实例分配空间,
         * 然后直接赋值给instance成员,然后再去初始化这个Singleton实例。这样就可能出错了,
         * 我们以A、B两个线程为例:
         * a>A、B线程同时进入了第一个if判断
         * b>A首先进入synchronized块,由于instance为null,所以它执行instance = new Singleton();
         * c>由于JVM内部的优化机制,JVM先画出了一些分配给Singleton实例的空白内存,
         * 并赋值给instance成员(注意此时JVM没有开始初始化这个实例),然后A离开了synchronized块。
         * d>B进入synchronized块,由于instance此时不是null
         *   因此它马上离开了synchronized块并将结果返回给调用该方法的程序。
         * e>此时B线程打算使用Singleton实例,却发现它没有被初始化,于是错误发生了。
         * 最終解決方法參見  饿汉单例 模式  Singleton2.java
         */
        public static Singleton1 getInstance() {
                if (instance == null) {
                        synchronized (instance) {
                                if (instance == null) {
                                        instance = new Singleton1();
                                }
                        }
                }
                return instance;
        }

        /* 如果该对象被用于序列化,可以保证对象在序列化前后保持一致 */
        public Object readResolve() {
                return instance;
        }
}

作者: 迷茫不堪的年纪    时间: 2015-10-20 23:34
洗洗考究,不能让你白写哈
作者: Sayman    时间: 2015-10-21 13:44
学习下!!!




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2