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; }
    

     

  • 相关阅读:
    知道回答C语言中如何返回值为数组
    指向字符串的指针和char类型的数组
    vba--将excel单元格格式改为常规格式
    vba--分拆工作薄
    VBA-合并多个工作簿
    使用sqlcel导入数据时出现“a column named '***' already belongs to this datatable”问题的解决办法
    使用Sqlcel操作数据库整理数据视频
    SQLCel匹配原数据信息,更新原数据所有信息并插入新数据的过程
    计算订单签收率的sql查询思路与过程(涉及百分比和四舍五入)
    sqlCel查询一个表中部分字段的数据后插入到另一个表中
  • 原文地址:https://www.cnblogs.com/zfinding/p/10512743.html
Copyright © 2011-2022 走看看