zoukankan      html  css  js  c++  java
  • java设计模式——单例模式

    1.饿汉式

     线程安全,不管用不用都会创建对象,拿空间换时间。

    /**
     * 饿汉式
     */
    public class Singleton {
        private static Singleton instance = new Singleton ();
    
        private Singleton () {}
    
        public static Singleton getInstance() {
            return instance;
        }
    }
    

     

    2.懒汉式

     进行一次非空判断,可能会出现一个或多个线程同时进入if语句,创建多个对象,线程不安全。

    /**
     * 懒汉式
     */
    public class Singleton {
        private static Singleton instance;
    
        private Singleton () {}
    
        public static Singleton getInstance() {
            if(instance == null) {
           instance = new Singleton();
         }
         return instance; } }

     

    3.懒汉式同步锁版

     虽然线程安全,但是锁范围较大,效率较低。

    /**
     * 懒汉线程同步锁版
     */
    class Singleton {
        private static Singleton instance;
    
        private Singleton() {}
    
        public synchronized static Singleton getInstance() {
            if(instance == null) {
                instance = new Singleton();
            }
            return instance;
        }
    }

     

    4.懒汉式双重检验锁版

    依然存在问题instance = new Singleton()这行在JVM大致做了如下操作:
    1.给instance分配内存
    2.调用Singleton构造函数初始化成员变量
    3.将instance对象指向分配的内存空间,执行完这一步,instance就不为null了
    JVM 的即时编译器中存在指令重排序的优化。也就是说上面的第二步和第三步的顺序是不能保证的,所以此行不是一个原子操作
    在 3 执行完毕、2 未执行之前,被线程二抢占了,这时 instance 已经是非 null 了(但却没有初始化),所以线程二会直接返回 instance,然后使用,最后报错。

    class Singleton {
        private static Singleton instance;
    
        private Singleton() {}
    
        public static Singleton getInstance() {
            if(instance == null) {
                synchronized(Singleton.class){
                    if(instance == null) {
                         instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }    
    

     

     5.懒汉式双重检验锁最终版

    使用volatile关键字来解决上一版的问题,在这里volatile的作用是禁止JVM的指令重排序优化,而不是利用可见性。

    /**
     * 双重检验锁最终版
     */
    
    public class Singleton{
        private volatile static Singleton instance;
    
        private Singleton() {}
    
        public static Singleton getInstance() {
            if (instance == null) {
                synchronized (Singleton.class) {
                    if (instance == null) {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }
    

     

     6.静态内部类版

      由于JVM特殊机制,线程安全,无效率缺陷,属于懒汉式。

    //静态内部类版
    public class Singleton { private static class SingletonHolder { private static Singleton INSTANCE = new Singleton (); } private Singleton () {} public static final Singleton getInstance() { return SingletonHolder.INSTANCE; }

     

     7.写法最简单的单例-枚举版

    //枚举版 线程安全
    public enum EasySingleton{ INSTANCE; }
    

     

  • 相关阅读:
    ftp 传文件完整代码(二)
    生成文件 权限 以及ftp 传数据(一)
    定时任务配置
    发送电子邮件遇到问题
    mysql 主从分离配置
    知道开始时间结束时间 计算这之间一共多少天
    mysql 语句集(二)
    mysql 的sql文件导出导入
    mysql 批量添加 更新
    Spring Boot中如何干掉if else
  • 原文地址:https://www.cnblogs.com/zfinding/p/10512743.html
Copyright © 2011-2022 走看看