一、懒汉模式:
public class Singleton { private static Singleton instance; private Singleton (){} public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }可以延迟加载,但线程不安全。
二、懒汉模式变种:
public class Singleton { private static Singleton instance; private Singleton (){} public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }跟一相比,使用了synchronized关键字,既可以延迟加载,又线程安全,但是执行效率低。
三、恶汉模式:
public class Singleton { private static Singleton instance = new Singleton(); private Singleton (){} public static Singleton getInstance() { return instance; } }
基于classloader机制,在类装载时就实例化,可以避免线程安全问题,但是没有延迟加载。
四、恶汉模式变种:
public class Singleton { private Singleton instance = null; static { instance = new Singleton(); } private Singleton (){} public static Singleton getInstance() { return this.instance; } }原理同三,只是把实例化操作放到了静态块里,优缺点同三。
五、双重校验锁:
public class Singleton { private volatile static Singleton singleton; private Singleton (){} public static Singleton getSingleton() { if (singleton == null) { synchronized (Singleton.class) { if (singleton == null) { singleton = new Singleton(); } } } return singleton; } }这实际上是懒汉模式的优化版,拥有线程安全、高效率以及延迟加载等特性。但是这种方式需要jdk1.5以上,且在一些平台和编译器下有错。
六、静态内部类:
public class Singleton { private static class SingletonHolder { private static final Singleton INSTANCE = new Singleton(); } private Singleton (){} public static final Singleton getInstance() { return SingletonHolder.INSTANCE; } }这实际上是恶汉模式的优化版,在类被装载时,静态内部类并没有被实例化,只有getInstance()时才 会装载 SingletonHolder 类,静态内部类方式也能很好地,实现线程安全、高效率和延迟加载特性。
七、枚举:
一个例子介绍。
public enum SingletonEnum { INSTANCE01,INSTANCE02; private String name; publicString getName() { returnname; } publicvoid setName(String name) { this.name = name; } } 测试 public class Test { public static void main(String[] args) { SingletonEnum instance01=SingletonEnum.INSTANCE01; instance01.setName("terje"); System.out.println(instance01.getName()); SingletonEnum instance02=SingletonEnum.INSTANCE01; System.out.println(instance02.getName()); SingletonEnum instance03=SingletonEnum.INSTANCE02; instance03.setName("liu"); System.out.println(instance03.getName()); SingletonEnum instance04=SingletonEnum.INSTANCE02; instance04.setName("liu"); System.out.println(instance04.getName()); } }
这种方式是Effective Java作者Josh Bloch 提倡的方式,它不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象,可谓是很坚强的壁垒;但是这种方式也需要jdk1.5以上版本。