1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.lang3.concurrent;
18
19 import static org.junit.jupiter.api.Assertions.assertEquals;
20 import static org.junit.jupiter.api.Assertions.assertFalse;
21 import static org.junit.jupiter.api.Assertions.assertNotNull;
22 import static org.junit.jupiter.api.Assertions.assertTrue;
23
24 import java.util.concurrent.CountDownLatch;
25
26 import org.apache.commons.lang3.AbstractLangTest;
27 import org.junit.jupiter.api.Test;
28
29
30
31
32
33
34
35
36
37
38
39
40 public abstract class AbstractConcurrentInitializerTest<T> extends AbstractLangTest {
41
42 static final class GetThread extends Thread {
43
44 private Object object;
45 private final CountDownLatch startLatch;
46 private final ConcurrentInitializer<?> initializer;
47
48 GetThread(final CountDownLatch startLatch, final ConcurrentInitializer<?> initializer) {
49 this.startLatch = startLatch;
50 this.initializer = initializer;
51 }
52
53 @Override
54 public void run() {
55 try {
56
57 startLatch.await();
58
59 object = initializer.get();
60 } catch (final InterruptedException iex) {
61
62 } catch (final ConcurrentException cex) {
63 object = cex;
64 }
65 }
66 }
67
68
69
70
71
72
73 protected abstract ConcurrentInitializer<T> createInitializer();
74
75
76
77
78
79
80 @Test
81 void testGet() throws ConcurrentException {
82 assertNotNull(createInitializer().get(), "No managed object");
83 }
84
85
86
87
88
89
90
91 @Test
92 void testGetConcurrent() throws ConcurrentException, InterruptedException {
93 final ConcurrentInitializer<T> initializer = createInitializer();
94 final int threadCount = 20;
95 final CountDownLatch startLatch = new CountDownLatch(1);
96 final GetThread[] threads = new GetThread[threadCount];
97 for (int i = 0; i < threadCount; i++) {
98 threads[i] = new GetThread(startLatch, initializer);
99 threads[i].start();
100 }
101
102
103 startLatch.countDown();
104 for (final Thread t : threads) {
105 t.join();
106 }
107
108
109 final Object managedObject = initializer.get();
110 for (final GetThread t : threads) {
111 assertEquals(managedObject, t.object, "Wrong object");
112 }
113 }
114
115
116
117
118
119
120 @Test
121 void testGetMultipleTimes() throws ConcurrentException {
122 final ConcurrentInitializer<T> initializer = createInitializer();
123 final Object obj = initializer.get();
124 for (int i = 0; i < 10; i++) {
125 assertEquals(obj, initializer.get(), "Got different object at " + i);
126 }
127 }
128
129
130
131
132
133
134 @Test
135 void testisInitialized() throws Throwable {
136 final ConcurrentInitializer<T> initializer = createInitializer();
137 if (initializer instanceof AbstractConcurrentInitializer) {
138 @SuppressWarnings("unchecked")
139 final AbstractConcurrentInitializer<T, Exception> castedInitializer = (AbstractConcurrentInitializer<T, Exception>) initializer;
140 assertFalse(castedInitializer.isInitialized(), "was initialized before get()");
141 assertNotNull(castedInitializer.get(), "No managed object");
142 assertTrue(castedInitializer.isInitialized(), "was not initialized after get()");
143 }
144 }
145 }