• 单例模式的七种写法


    单例模式的七种写法

    1. 饿汉式

    线程安全 比较好的一种写法

    且利用 jvm的双亲委派机制 保证线程问题(只加载一次)

    缺点:不管用没用到 都会被加载到jvm中

    public class EHanShiSingleton{
        private static final EHanShiSingleton INSTANCE = new EHanShiSingleton();
        
    	private EHanShiSingleton(){};
       
    	public static EHanShiSingleton getInstance(){
        	return INSTANCE;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2. 普通 懒汉式

    缺点:多线程中会被多次实例化

    public class LanHanShiSingleton{
        private static LanHanShiSingleton INSTANCE = null;
    
        private LanHanShiSingleton(){};
    
        public static LanHanShiSingleton getInstance(){
            if(INSTANCE == null){
                INSTANCE = new LanHanShiSingleton();
            }
            return INSTANCE;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3. 加锁 懒汉式

    缺点:还是在多线程中会被多次实例化 只是排队了

    public class LanHanShiSingleton{
        private static LanHanShiSingleton INSTANCE = null;
    
        private LanHanShiSingleton(){};
    
        public static LanHanShiSingleton getInstance(){
            if(INSTANCE == null){
                // 加锁
                synchronized(LanHanShiSingleton.class){
                    INSTANCE = new LanHanShiSingleton();
                }
            }
            return INSTANCE;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    4. 双检锁 懒汉式

    缺点:浪费资源、效率不高

    public class LanHanShiSingleton{
    	// volatile 防止指令重排
        private static volatile LanHanShiSingleton INSTANCE = null;
    
        private LanHanShiSingleton(){};
    
        public static LanHanShiSingleton getInstance(){
            if(INSTANCE == null){
                synchronized(LanHanShiSingleton.class){
                    // 加锁后 二次判断
                    if(INSTANCE == null){
                        INSTANCE = new LanHanShiSingleton();
                    }
                }
            }
            return INSTANCE;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    5. CAS乐观锁 懒汉式

    缺点:CAS存在忙等的问题,可能会造成CPU资源的浪费。

    public class LanHanShiSingleton{
        private static final AtomicReference<LanHanShiSingleton> INSTANCE = new AtomicReference<>();
    
        private LanHanShiSingleton(){};
    
        public static LanHanShiSingleton getInstance(){
            for(;;){
                if(INSTANCE.get()==null){
                    LanHanShiSingleton NEW_INSTANCE = new LanHanShiSingleton();
                    INSTANCE.compareAndSet(null,NEW_INSTANCE);
                }
            }
            return INSTANCE.get();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    6. 内部类 单例

    利用 内部类 实现懒加载

    利用 jvm的双亲委派机制 保证不会在多线程中重复加载

    public class Singleton{
        private Singleton() {}
    
        private final static GetSingleton() {
            private final static Singleton INSTANCE = new Singleton();
        }
    
        private static Singleton getInstance(){
            return GetSingleton.INSTANCE;
        } 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    7.《Effective Java》 作者推荐版 单例模式

    利用枚举类实现单例模式。

    同时枚举类也自动提供了序列化机制,只是枚举类无法实现继承,所以如果想要扩展就需要通过接口的方式实现。

    public enum Singleton{
        INSTANCE;
    }
    
    • 1
    • 2
    • 3
  • 相关阅读:
    ElasticSearch--优化写入速度的方法--修改配置
    力扣Hot100-994腐烂的橘子
    gin框架和logrus自定义日志输出,使日志输出到终端同时写到文件
    【PAT甲级 - C++题解】1072 Gas Station
    linux常用环境配置
    深入理解操作系统之线程
    【AI大模型-什么是大模型】
    【天幕系列 02】开源力量:揭示开源软件如何成为技术演进与社会发展的引擎
    Scala学习:类和对象
    SAS @和@@的区别
  • 原文地址:https://blog.csdn.net/qq_43652321/article/details/127698371