参考资料:http://blog.csdn.net/haoel/article/details/4028232
public class SingletonTest implements Runnable { static SingletonClass1 instance = null; public static void main(String args[]) { // SingletonClass0 instance = new SingletonClass0();// The constructor // SingletonClass0() is not visible for (int i = 0; i < 15; i++) { new Thread(new SingletonTest()).start(); } // System.out.println(instance.getClass()); } @Override public void run() { // TODO Auto-generated method stub SingletonClass6.getInstance(); // System.out.println(SingletonClass7.instance.hashCode()); } } class SingletonClass0 { private static SingletonClass0 instance = null; private SingletonClass0() { System.out.println("constructor run"); } public static SingletonClass0 getInstance() {// wrong 单线才单线程下没问题,多线程下仍会有多个实例 if (instance == null) { instance = new SingletonClass0(); System.out.println(instance.hashCode()); } return instance; } } class SingletonClass1 { private static SingletonClass1 instance = null; private SingletonClass1() { System.out.println("constructor run"); } public static SingletonClass1 getInstance() {// wrong 多线程下仍会有多个实例,与上一种 // 区别在于过个线程的new过程被同步了 if (instance == null) { synchronized (SingletonClass1.class) { instance = new SingletonClass1(); System.out.println(instance.hashCode()); } } return instance; } } class SingletonClass2 { private static SingletonClass2 instance = null; private SingletonClass2() { System.out.println("constructor run"); } public static SingletonClass2 getInstance() { synchronized (SingletonClass2.class) {// right。只会有一个线程new实例,但阻碍了后续线程读实例 if (instance == null) { instance = new SingletonClass2(); System.out.println(instance.hashCode()); } } return instance; } } class SingletonClass3 { private static SingletonClass3 instance = null; private SingletonClass3() { System.out.println("constructor run"); } public static SingletonClass3 getInstance() { synchronized (SingletonClass3.class) {// right // 只会有一个线程new实例,不会影响后续线程读实例,但instance=new // SingletonClass3()在JVM内不是原子操作,内部的几个步骤可能乱序,从而出错 if (instance == null) { synchronized (SingletonClass1.class) { if (instance == null) { instance = new SingletonClass3(); System.out.println(instance.hashCode()); } } } } return instance; } } class SingletonClass4 { private static volatile SingletonClass4 instance = null;// right // 只有一个实例,volatite保证了在JVM内部new // instance的几个操作禁止指令重排序优化 private SingletonClass4() { System.out.println("constructor run"); } public static SingletonClass4 getInstance() { synchronized (SingletonClass4.class) { if (instance == null) { synchronized (SingletonClass1.class) { if (instance == null) { instance = new SingletonClass4(); System.out.println(instance.hashCode()); } } } } return instance; } } class SingletonClass5 {// right,但是由类加载器在类加载时创建实例,我们无法控制实例创建的时机以干一些事(比如某个配置文件,或是某个被其它类创建的资源) public volatile static SingletonClass5 instance = new SingletonClass5(); private SingletonClass5() { System.out.println("constructor run"); }; public static SingletonClass5 getInstance() { System.out.println(instance.hashCode()); return instance; } } class SingletonClass6 {// 仍然使用JVM本身机制保证了线程安全问题;由于 SingletonHolder 是私有的,除了 // getInstance() // 之外没有办法访问它,因此它只有在getInstance()被调用时才会真正创建;同时读取实例的时候不会进行同步,没有性能缺陷;也不依赖 // JDK 版本 private static class SingletonHolder { private static final SingletonClass6 INSTANCE = new SingletonClass6(); } private SingletonClass6() { System.out.println("constructor run"); } public static final SingletonClass6 getInstance() { System.out.println(SingletonHolder.INSTANCE.hashCode()); return SingletonHolder.INSTANCE; } } class SingletonClass7 { public SingletonClass7() { System.out.println("constructor run"); } } enum SingletonClass { instance; }
时间: 2024-10-12 05:04:55