- 饿汉模式
1 class Singleton{ 2 3 private static final Singleton instance= new Singleton(); 4 5 private Singleton() { 6 } 7 8 public static Singleton getInstance(){ 9 return instance; 10 } 11 12 }
类加载时初始化。
- 饱汉模式(线程不安全)
class Singleton{ private static Singleton instance; private Singleton() { } public static Singleton getInstance(){ if (instance == null){ instance = new Singleton(); } return instance; } }
线程不安全,懒加载。
- 饱汉模式(线程安全)
class Singleton { private static Singleton instance; private Singleton() { } public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
线程安全,懒加载,效率低。
- 双重检查锁
public class Singleton { private volatile static Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } public static void main(String[] args) { Thread t1 = new Thread(new Runnable() { @Override public void run() { System.out.println(Singleton.getInstance().hashCode()); } },"t1"); Thread t2 = new Thread(new Runnable() { @Override public void run() { System.out.println(Singleton.getInstance().hashCode()); } },"t2"); Thread t3 = new Thread(new Runnable() { @Override public void run() { System.out.println(Singleton.getInstance().hashCode()); } },"t3"); t1.start(); t2.start(); t3.start(); } }
为什么要双重检查?多个线程可能进入同步代码块外的if语句。为什么要加volatile? 实例化时可能指令重排,类未初始化之前先把instance指向了内存地址,此时另一线程调用会非NULL返回使用报错。
- 静态内部类
public class InnerSingleton { private InnerSingleton(){}
private static class SingletonHolder{ private static InnerSingleton instance = new InnerSingleton(); } public static InnerSingleton getInstance(){ return SingletonHolder.instance; } }静态内部类不绑定外部类的实例,所以调用时加载,懒汉式,不依赖jdk版本。
- 枚举
public enum EnumSingleton { //定义一个枚举元素,就代表了Singleton的一个实例。 uniqueInstance; //单例有自己的操作 public void singletonOperation(){ //功能处理 System.out.println("finish"); } public static void main(String[] args) { EnumSingleton enumSingleton = EnumSingleton.uniqueInstance; enumSingleton.singletonOperation(); } }
枚举创建默认线程安全。
- 单例模式确保此类只有一个实例,自行实例化并提供一个访问的全局共有静态方法。