-
懒汉模式——线程不安全写法
1 //这种写法不适合多线程下使用,多线程下有可能会被创建出多个Singleton实例 2 public class Singleton { 3 //私有静态变量,使其只在内存中加载一份 4 private static Singleton instance; 5 //私有化构造方法,使其无法被new出实例 6 private Singleton (){} 7 8 //静态方法构造对象并返回 9 public static Singleton getInstance() { 10 if (instance == null) { 11 instance = new Singleton(); 12 } 13 return instance; 14 } 15 }
-
懒汉模式——线程安全写法
1 //实例化对象的方法加入同步关键字声明,使得线程安全 2 public class Singleton { 3 private static Singleton instance; 4 private Singleton (){} 5 6 //在同步方法中创建实例对象,多线程时安全。 7 public static synchronized Singleton getInstance() { 8 if (instance == null) { 9 instance = new Singleton(); 10 } 11 return instance; 12 } 13 }
-
懒汉模式——双重锁检查
1 /** 2 * 双重锁检查机制: 3 * 创建对象实例的方法中检查两次对象是否为空 4 * 加锁之后在检查一次 5 * volatile:保证了内存可见性 6 */ 7 public class Singleton { 8 private volatile static Singleton singleton; 9 private Singleton (){} 10 public static Singleton getSingleton() { 11 if (singleton == null) { //Single Checked 12 synchronized (Singleton.class) { 13 if (singleton == null) { //Double Checked 14 singleton = new Singleton(); 15 } 16 } 17 } 18 return singleton; 19 } 20 }
-
饿汉模式
1 public class Singleton { 2 //在声明变量的同时创建出实例对象,加了static关键字修饰,使其只在堆中创建一次 3 private static Singleton instance = new Singleton(); 4 private Singleton (){} 5 public static Singleton getInstance() { 6 return instance; 7 } 8 }
-
饿汉模式——变种写法
1 public class Singleton { 2 private Singleton instance = null; 3 //类加载时,在静态代买块中创建实例对象 4 static { 5 instance = new Singleton(); 6 } 7 private Singleton (){} 8 public static Singleton getInstance() { 9 return this.instance; 10 } 11 }
-
静态内部类
1 /** 2 *Singleton类被装载instance不一定被初始化,因为内部类SingletonHolder没有被主动使用,只有显示*调用getInstance才会显示装载SingletonHolder 类,从而实例化instance 3 */ 4 public class Singleton { 5 private static class SingletonHolder { 6 //声明对象为常量形式 7 private static final Singleton INSTANCE = new Singleton(); 8 } 9 private Singleton (){} 10 public static final Singleton getInstance() { 11 return SingletonHolder.INSTANCE; 12 } 13 }
-
枚举
1 /** 2 *枚举(既可以避免多线程同步问题,还可以防止被反序列化重建对象) 3 */ 4 public enum Singleton { 5 INSTANCE; 6 public void whateverMethod() { 7 } 8 public static void main(String[] args) { 9 Singleton s = Singleton.INSTANCE; 10 Singleton s2 = Singleton.INSTANCE; 11 System.out.println(s==s2); 12 } 13 }