懒汉式
- 使用时才实例化
- 使用场景:单例使用次数不多、功能复杂,占用内存大、实例化时间长、特定场景、延迟加载。
- ==线程不安全==:多个线程可能会并发调用他的newInstance方法导致多个线程可能会创建多份相同的单例出来。
1 2 3 4 5 6 7 8 9 10 11 12
| public class Singleton{ private static Singleton instance = null;
private Singleton(){}
public static Singleton newInstance(){ if(null == instance){ instance = new Singleton(); } return instance; } }
|
懒汉式同步锁
使用同步锁synchronized (Singleton.class)
解决线程不安全问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class Singleton { private static Singleton instance = null; private Singleton(){ } public static Singleton getInstance() { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } return instance; } }
|
双重校验锁
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public class Singleton { private static volatile Singleton instance = null; private Singleton(){ } public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } }
|
饿汉式
- 简单快速,实例化快
- 使用场景:占用内存较小的、应用启动时加载初始化的
- 线程安全:因为JVM只会加载一次单例类
1 2 3 4 5 6 7 8 9 10
| public class Singleton{
private static Singleton instance = new Singleton();
private Singleton(){}
public static Singleton newInstance(){ return instance; } }
|
jvm的类加载机制
JVM已经为我们提供了同步控制
- 在static{}区块中初始化的数据
- 访问final字段时
- …..
静态内部类
- 简洁
- 使用场景:
- 线程安全:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class Singleton{ private static class SingletonHolder{ public static Singleton instance = new Singleton(); }
private Singleton(){}
public static Singleton newInstance(){ return SingletonHolder.instance; }
public void doSomething(){ } }
|
枚举类
- 最简单
- 线程安全:
1 2 3 4 5 6 7 8
| public enum Singleton{ instance;
public void doSomething(){ } }
|
使用方法
1 2 3 4
| public static void main(String[] args){ Singleton singleton = Singleton.instance; singleton.doSomething(); }
|
参考
ANDROID设计模式之单例模式