zoukankan      html  css  js  c++  java
  • singleton单例模式小结

    1.饿汉模式

    public class SingletonEntity2 {
    
        // 在类加载的时候创建对象:饿汉模式
        public static SingletonEntity2 obj = new SingletonEntity2();
        
        // 构造方法私有化
        private SingletonEntity2(){}
        
        public static SingletonEntity2 getInstance(){
            return obj;
        }
        
    }

    2.懒汉模式

    public class SingletonEntity {
        
        // 静态变量存放在方法区中,类加载的时候赋值,而且只会赋值一次,懒汉模式
        public static SingletonEntity obj = null;
        
        // 构造方法私有化
        private SingletonEntity() {}
        
        // 对外提供获取实例的公开的静态的方法
        public static SingletonEntity getInstance() {
            if (obj == null) {
                obj = new SingletonEntity();
                System.out.println("新创建实例");
            }
            System.out.println("直接返回实例");
            return obj;
        }
        
    }

    3.测试类

    public static void main(String[] args) {
        
        SingletonEntity obj1 = SingletonEntity.getInstance();
        SingletonEntity obj2 = SingletonEntity.getInstance();
        System.out.println(obj1 == obj2); // true
    
    }

    ==========================================================================================================================================

    懒汉模式不安全性测试:

    1.起现成类:

    public class RunnableThreadTest implements Runnable {
        
        @Override
        public void run() {
            
            SingletonEntity obj = SingletonEntity.getInstance();
            System.out.println(Thread.currentThread().getName()+" "+obj);  
    
        }
    
    }

    2.测试类:

    public class SingletonTest {
    
        public static void main(String[] args) {
            
            Thread thread1 = new Thread(new RunnableThreadTest());
            Thread thread2 = new Thread(new RunnableThreadTest());
            thread1.start();
            thread2.start();
            
        }
    
    }

    3.运行结果:

    Thread-0 com.beijing.singleton.SingletonEntity@406866f9
    Thread-1 com.beijing.singleton.SingletonEntity@25eb939e

    ==========================================================================================================================================

    改善结果:推荐使用双检查锁机制

    public class SingletonEntity {
    
        // 静态变量存放在方法区中,类加载的时候赋值,而且只会赋值一次,懒汉模式
        public static volatile SingletonEntity obj = null;
    
        // 构造方法私有化
        private SingletonEntity() {
        }
    
        // 对外提供获取实例的公开的静态的方法
        public static SingletonEntity getInstance() {
            try {
                // 双检查所机制
                if (obj == null) {
                    synchronized (SingletonEntity.class) {
                        if (obj == null) {
                            Thread.sleep(1000);
                            obj = new SingletonEntity();
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return obj;
        }
    
    }
    为什么要用volatile修饰instance?
    原因:在于instance = new SingletonEntity()的时候,在内存中实际上是分3步执行的:
    1)分配对象的内存空间:memory = allocate();
    2)初始化对象:ctorInstance(memory);
    3)指向分配的地址:instance =memory
    多线程在执行的时候,2 3可能发生重排序。即有可能线程A执行到第3步的时候,读取到instance不为null,就返回。实际上此时还未执行第二部即未初始化。
    加上volatile就可以避免2 3步重排序来保证线程安全。
  • 相关阅读:
    Zend Framework 2.1.5 中根据服务器的环境配置调用数据库等的不同配置
    在基于 Eclipse 的 IDE 中安装和使用 Emmet(ZenCoding)
    【翻译】Emmet(Zen Coding)官方文档 之六 自定义 Emmet
    【翻译】Emmet(Zen Coding)官方文档 之二 缩写
    【翻译】Emmet(Zen Coding)官方文档 之七 一览表
    【翻译】Emmet(Zen Coding)官方文档 之三 CSS 缩写
    【翻译】Emmet(Zen Coding)官方文档 之四 动作
    【翻译】Emmet(Zen Coding)官方文档 之一 web 编程的必备工具
    Zend Framework 2 时区设置警告问题的解决
    【翻译】Emmet (Zen Coding) 元素类型
  • 原文地址:https://www.cnblogs.com/zhangjianbing/p/8066526.html
Copyright © 2011-2022 走看看