单例模式完全解析

1packagexylz.study.singleton;
2
3publicclassSingleton {
4
5privatestaticSingleton instance=null;
6
7privateSingleton() {
8 }
9
10publicstaticSingleton getInstance() {
11if(instance==null) {
12 instance=newSingleton();
13 }
14returninstance;
15 }
16}
17

1packagexylz.study.singleton;
2
3publicclassSynchronizedSingleton {
4
5privatestaticSynchronizedSingleton instance=null;
6
7privateSynchronizedSingleton() {
8 }
9
10publicstaticsynchronizedSynchronizedSingleton getInstance() {
11if(instance==null) {
12 instance=newSynchronizedSingleton();
13 }
14returninstance;
15 }
16}
17

1packagexylz.study.singleton;
2
3publicclassStaticSingleton {
4
5privatestaticStaticSingleton instance=newStaticSingleton();
6
7privateStaticSingleton() {
8 }
9
10publicstaticStaticSingleton getInstance() {
11returninstance;
12 }
13}
14

1packagexylz.study.singleton;
2
3publicclassDoubleLockSingleton {
4
5privatestaticDoubleLockSingleton instance=null;
6
7privateDoubleLockSingleton() {
8 }
9
10publicstaticDoubleLockSingleton getInstance() {
11if(instance==null) {
12synchronized(DoubleLockSingleton.class) {
13if(instance==null) {
14 instance=newDoubleLockSingleton();
15 }
16 }
17 }
18returninstance;
19 }
20}
21

指令重排序与happens-before法则。

package xylz.study.singleton;

public class DoubleLockSingleton {

private staticvolatileDoubleLockSingleton instance = null;

private DoubleLockSingleton() {
}

public static DoubleLockSingleton getInstance() {
if (instance == null) {
synchronized (DoubleLockSingleton.class) {
if (instance == null) {
instance = new DoubleLockSingleton();
}
}
}
return instance;
}
}

（1）《Java theory and practice: Fixing the Java Memory Model, Part 2》
（2）《Initialize-On-Demand Holder Class and Singletons》

1packagexylz.study.singleton;
2
3publicclassHolderSingleton {
4
5privatestaticclassHolderSingletonHolder {
6
7staticHolderSingleton instance=newHolderSingleton();
8 }
9
10privateHolderSingleton() {
11//maybe throw an Exception when doing something
12 }
13
14publicstaticHolderSingleton getInstance() {
15returnHolderSingletonHolder.instance;
16 }
17}
18

1packagexylz.study.singleton;
2
3publicclassHolderSingletonTest {
4
5privatestaticclassHolderSingletonHolder {
6
7staticHolderSingletonTest instance=newHolderSingletonTest();
8 }
9
10privatestaticbooleaninit=false;
11
12privateHolderSingletonTest() {
13//maybe throw an Exception when doing something
14if(!init) {
15 init=true;
16thrownewRuntimeException("fail");
17 }
18 }
19
20publicstaticHolderSingletonTest getInstance() {
21returnHolderSingletonHolder.instance;
22 }
23publicstaticvoidmain(String[] args) {
24for(inti=0;i<3;i++) {
25try{
26 System.out.println(HolderSingletonTest.getInstance());
27 }catch(Exception e) {
28 System.err.println("one->"+i);
29 e.printStackTrace();
30 }catch(ExceptionInInitializerError err) {
31 System.err.println("two->"+i);
32 err.printStackTrace();
33 }catch(Throwable t) {
34 System.err.println("three->"+i);
35 t.printStackTrace();
36 }
37 }
38 }
39}
40很不幸将得到以下输出：
1two->0
2java.lang.ExceptionInInitializerError
3 at xylz.study.singleton.HolderSingletonTest.getInstance(HolderSingletonTest.java:21)
4 at xylz.study.singleton.HolderSingletonTest.main(HolderSingletonTest.java:26)
5Caused by: java.lang.RuntimeException: fail
6 at xylz.study.singleton.HolderSingletonTest.<init>(HolderSingletonTest.java:16)
7 at xylz.study.singleton.HolderSingletonTest.<init>(HolderSingletonTest.java:12)
8 at xylz.study.singleton.HolderSingletonTest\$HolderSingletonHolder.<clinit>(HolderSingletonTest.java:7)
92more
10three->1
11java.lang.NoClassDefFoundError: Could not initializeclassxylz.study.singleton.HolderSingletonTest\$HolderSingletonHolder
12 at xylz.study.singleton.HolderSingletonTest.getInstance(HolderSingletonTest.java:21)
13 at xylz.study.singleton.HolderSingletonTest.main(HolderSingletonTest.java:26)
14three->2
15java.lang.NoClassDefFoundError: Could not initializeclassxylz.study.singleton.HolderSingletonTest\$HolderSingletonHolder
16 at xylz.study.singleton.HolderSingletonTest.getInstance(HolderSingletonTest.java:21)
17 at xylz.study.singleton.HolderSingletonTest.main(HolderSingletonTest.java:26)
18

Top