目录
单例模式7种实现及利弊分析
1.饿汉式
2.懒汉式(非线程安全)
3.懒汉式(synchronized)
4.懒汉式(静态内部类)
5.懒汉式(双重锁DCL)
6.懒汉式(ThreadLocal)
7.枚举类型(建议使用)
单例模式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; } }
优点:安全,避免了反射攻击,编码简单
缺点:无法实现懒加载,无法被继承