Skip to content

Commit 96241f6

Browse files
committed
iluwatar#100 Added test case for demonstrating the thread safety issues of a
naive lazy loaded Singleton implementation.
1 parent db6ec3c commit 96241f6

File tree

1 file changed

+70
-0
lines changed

1 file changed

+70
-0
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package com.iluwatar.singleton;
2+
3+
import org.junit.Test;
4+
5+
/**
6+
*
7+
* This test case demonstrates thread safety issues of lazy loaded Singleton implementation.
8+
*
9+
* Out of the box you should see the test output something like the following:
10+
*
11+
* Thread=Thread-4 got instance=com.iluwatar.singleton.LazyLoadedSingletonThreadSafetyTest$LazyLoadedIvoryTower@6fde356e
12+
* Thread=Thread-2 creating instance=com.iluwatar.singleton.LazyLoadedSingletonThreadSafetyTest$LazyLoadedIvoryTower@6fde356e
13+
* Thread=Thread-0 creating instance=com.iluwatar.singleton.LazyLoadedSingletonThreadSafetyTest$LazyLoadedIvoryTower@6fde356e
14+
* Thread=Thread-0 got instance=com.iluwatar.singleton.LazyLoadedSingletonThreadSafetyTest$LazyLoadedIvoryTower@6fde356e
15+
* Thread=Thread-3 got instance=com.iluwatar.singleton.LazyLoadedSingletonThreadSafetyTest$LazyLoadedIvoryTower@6fde356e
16+
* Thread=Thread-1 got instance=com.iluwatar.singleton.LazyLoadedSingletonThreadSafetyTest$LazyLoadedIvoryTower@60f330b0
17+
* Thread=Thread-2 got instance=com.iluwatar.singleton.LazyLoadedSingletonThreadSafetyTest$LazyLoadedIvoryTower@6fde356e
18+
*
19+
* By changing the method signature of LazyLoadedIvoryTower#getInstance from
20+
* public static LazyLoadedIvoryTower getInstance()
21+
* into
22+
* public synchronized static LazyLoadedIvoryTower getInstance()
23+
* you should see the test output change to something like the following:
24+
*
25+
* Thread=Thread-4 creating instance=com.iluwatar.singleton.LazyLoadedSingletonThreadSafetyTest$LazyLoadedIvoryTower@3c688490
26+
* Thread=Thread-4 got instance=com.iluwatar.singleton.LazyLoadedSingletonThreadSafetyTest$LazyLoadedIvoryTower@3c688490
27+
* Thread=Thread-0 got instance=com.iluwatar.singleton.LazyLoadedSingletonThreadSafetyTest$LazyLoadedIvoryTower@3c688490
28+
* Thread=Thread-3 got instance=com.iluwatar.singleton.LazyLoadedSingletonThreadSafetyTest$LazyLoadedIvoryTower@3c688490
29+
* Thread=Thread-2 got instance=com.iluwatar.singleton.LazyLoadedSingletonThreadSafetyTest$LazyLoadedIvoryTower@3c688490
30+
* Thread=Thread-1 got instance=com.iluwatar.singleton.LazyLoadedSingletonThreadSafetyTest$LazyLoadedIvoryTower@3c688490
31+
*
32+
*/
33+
public class LazyLoadedSingletonThreadSafetyTest {
34+
35+
private static final int NUM_THREADS = 5;
36+
37+
@Test
38+
public void test() {
39+
SingletonThread runnable = new SingletonThread();
40+
for (int j=0; j<NUM_THREADS; j++) {
41+
Thread thread = new Thread(runnable);
42+
thread.start();
43+
}
44+
}
45+
46+
private static class SingletonThread implements Runnable {
47+
48+
@Override
49+
public void run() {
50+
LazyLoadedIvoryTower instance = LazyLoadedIvoryTower.getInstance();
51+
System.out.println("Thread=" + Thread.currentThread().getName() + " got instance=" + instance);
52+
}
53+
}
54+
55+
private static class LazyLoadedIvoryTower {
56+
57+
private static LazyLoadedIvoryTower instance = null;
58+
59+
private LazyLoadedIvoryTower() {
60+
}
61+
62+
public static LazyLoadedIvoryTower getInstance() {
63+
if (instance == null) {
64+
instance = new LazyLoadedIvoryTower();
65+
System.out.println("Thread=" + Thread.currentThread().getName() + " creating instance=" + instance);
66+
}
67+
return instance;
68+
}
69+
}
70+
}

0 commit comments

Comments
 (0)