单例模式6种实现及利弊分析

单例模式7种实现及利弊分析

单例模式三要素

  • 私有的构造方法;
  • 指向自己实例的私有静态引用;
  • 以自己实例为返回值的静态的公有方法

1.饿汉式

public class Singleton {
    private static Singleton singleton = new Singleton();

    private Singleton(){};
    
    public static Singleton getSingleton(){
        return singleton;
    }
}

优点:线程安全,在类加载完成时就完成了初始化,调用效率高

缺点:类加载较慢,无法达到懒加载的效果

2.懒汉式(非线程安全)

public class Singleton{
	private static Singleton singleton;
    
    private Singleton(){};
    
    public static Singleton getSingleton(){
		if(singleton == null){
            singleton = new Singleton();
        }
    	return singleton;
    }
}

优点:节约资源,实现懒加载

缺点:非线程安全,获取对象需要实例化,调用效率低

3.懒汉式(synchronized)

public class Singleton{
	private static Singleton singleton;
    
    private Singleton(){};
    
    //	1.synchronized块 实现线程安全
    /*public static Singleton getSingleton(){
        synchronized(Singleton.class){
        	if(singleton == null){
                singleton = new Singleton();
            }
            return singleton;
        }       
    }
    */
    
    //	2.synchronized方法 实现线程安全
    public static synchronized Singleton getSingleton(){
		if(singleton == null){
            singleton = new Singleton();
        }
    	return singleton;
    }
}

优点:线程安全,实现懒加载

缺点:获取对象需要实例化,调用效率低

4.懒汉式(静态内部类)

public class Singleton{
    private static class Holder{
        private static Singleton singleton = new Singleton();
    }
    
	private Singleton(){};
    
    public static Singleton getSingleton(){
        return Holder.singleton;
    }
}

优点:线程安全,实现懒加载

缺点:暂无

5.懒汉式(双重锁DCL)

public class Singleton{
    //volatile禁止指令重排序,避免DCL失效问题
    private static volatile Singleton singleton;
    
    private Singleton(){};
    
    public static Singleton getSingleton(){
        //避免重复的同步
        if(singleton == null){
            //如果未实例化,才进行加锁
            synchronized(Singleton.class){
                if(singleton == null){
		      singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}

优点:线程安全,实现懒加载

缺点:能被反射破解,不是绝对安全

6.懒汉式(ThreadLocal)

public class Singleton {
    private static volatile Singleton singleton;
    private static ThreadLocal<Singleton> threadLocal = new ThreadLocal<>();

    private Singleton(){};

    public static void createSingleton(){
        synchronized (Singleton.class){
            if (singleton == null){
                singleton = new Singleton();
            }
        }
        threadLocal.set(singleton);
    }

    public static Singleton getSingleton(){
        if(threadLocal.get() == null){
            createSingleton();
        }
        return singleton;
    }
}

优点:也相当于实现了双重检查,线程安全

缺点:效率不及传统双重检查

7.枚举类型(建议使用)

public enum  Singleton {
    INSTANCE;
    public Singleton getSingleton(){
        return INSTANCE;
    }
}

优点:安全,避免了反射攻击,编码简单

缺点:无法实现懒加载,无法被继承

posted @ 2021-01-03 10:53  Zzzkis  阅读(312)  评论(5编辑  收藏  举报