七种单例模式的写法
-
饿汉式
特点:在类加载时实例化,线程安全,如果没有使用instance的话比较耗费资源
class SingletonDemo { private static volatile SingletonDemo instance = new SingletonDemo(); private SingletonDemo() { System.out.println("构造方法被调用了 " + Thread.currentThread().getName()); } public static SingletonDemo getInstance() { return instance; } }
-
懒汉式(非线程安全)
特点: 使用时再实例化
class SingletonDemo { private static volatile SingletonDemo instance = null; private SingletonDemo() { System.out.println("构造方法被调用了 " + Thread.currentThread().getName()); } public static SingletonDemo getInstance() { if (instance == null) { instance = new SingletonDemo(); } return instance; } }
-
懒汉式(线程安全)
特点:线程安全,使用synchronized关键字锁方法,多线程的情况下方法使用次数很多的话会严重影响效率
class SingletonDemo { private static volatile SingletonDemo instance = null; private SingletonDemo() { System.out.println("构造方法被调用了 " + Thread.currentThread().getName()); } public static synchronized SingletonDemo getInstance() { if (instance == null) { instance = new SingletonDemo(); } return instance; } }
-
饿汉(变种)
跟上面的饿汉的区别仅是写法 初始化代码写在了静态代码块
class SingletonDemo { private static volatile SingletonDemo instance = null; static { instance = new SingletonDemo(); } private SingletonDemo() { System.out.println("构造方法被调用了 " + Thread.currentThread().getName()); } public static SingletonDemo getInstance() { return instance; } }
-
懒汉(静态内部类)
特点:线程安全, 用时加载,使用静态内部类
class SingletonDemo { private static class InnerClass { private static final SingletonDemo instance = new SingletonDemo(); } private SingletonDemo() {} public SingletonDemo getInstance() { return InnerClass.instance; } }
-
饿汉(枚举)
利用枚举
enum SingletonDemo { INSTANCE; public void someMethod() { sout("enum Singleton"); } }
-
懒汉(DCL)
public class VolatileDemo { public static void main(String[] args) { for (int i = 0; i < 10; i++) { new Thread(() -> { SingletonDemo.getInstance(); }, String.valueOf(i)).start(); } } } class SingletonDemo { private static volatile SingletonDemo instance = null; private SingletonDemo() { System.out.println("构造方法被调用了 " + Thread.currentThread().getName()); } public static SingletonDemo getInstance() { if (instance == null) { synchronized (SingletonDemo.class) { if (instance == null) { instance = new SingletonDemo(); } } } return instance; } }
对比
-
根据实例化时机
-
根据是否线程安全
是否线程安全 方式 饿汉式 线程安全 饿汉式 懒汉式(非线程安全) 非线程安全 懒汉式 懒汉式(线程安全) 线程安全 懒汉式 饿汉(变种) 线程安全 饿汉式 懒汉(静态内部类) 线程安全 懒汉式 饿汉(枚举) 线程安全 饿汉式 懒汉(DCL) 线程安全 懒汉式