A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© kamo 中级黑马   /  2015-10-18 18:30  /  1145 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

   这个比较短,我就贴下代码,这都是个人,从网上搜搜,思考,总结的,
需要有一点基础的,想全面点了解的可以看看。
   希望能对大家有帮助。
/*
* 懒汉式单例
* 类进内存对象还没有存在,只有调用方法时才建立对象
*对象是方法被调用时才初始化,也叫做对象的延时加载
*它是线程不安全的,并发环境下很可能出现多个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;
        }
}

4 个回复

倒序浏览
洗洗考究,不能让你白写哈

点评

谢谢  发表于 2015-10-21 14:05
回复 使用道具 举报
学习下!!!

点评

谢谢  发表于 2015-10-21 14:03
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马