/** * * 单例模式 * @author * */ public class Singleton { private static Singleton instance = null; private Singleton() { super(); } /** * 很影响性能:每次调用getInstance方法的时候都必须获得Singleton的锁, * 而实际上,当单例实例被创建以后,其后的请求没有必要再使用互斥机制了 * @return */ public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } /** * 1. A、B线程同时进入了第一个if判断 * * 2. A首先进入synchronized块,由于instance为null,所以它执行instance = new Singleton(); * * 3. * 由于JVM内部的优化机制,JVM先画出了一些分配给Singleton实例的空白内存,并赋值给instance成员(注意此时JVM没有开始初始化这个实例 * ),然后A离开了synchronized块。 * * 4. * B进入synchronized块,由于instance此时不是null,因此它马上离开了synchronized块并将结果返回给调用该方法的程序。 * * 5. 此时B线程打算使用Singleton实例,却发现它没有被初始化,于是错误发生了。 */ public static Singleton getInstance1() { if (instance == null) { synchronized (instance) { if (instance == null) { return new Singleton(); } } } return instance; } /** * JVM内部的机制能够保证当一个类被加载的时候,这个类的加载过程是线程互斥的。这样当我们第一次调用getInstance的时候, * JVM能够帮我们保证instance只被创建一次 , * 并且会保证把赋值给instance的内存初始化完毕,这样我们就不用担心3.2中的问题。 * 此外该方法也只会在第一次调用的时候使用互斥机制,这样就解决了3 * .1中的低效问题。最后instance是在第一次加载SingletonContainer类时被创建的, * 而SingletonContainer类则在调用getInstance方法的时候才会被加载,因此也实现了惰性加载。 */ private static class SingletonContainer { private static Singleton instance = new Singleton(); } public static Singleton getInstance2() { return SingletonContainer.instance; } public void doSomething() { } }