ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/AbstractQueuedSynchronizerTest.java
Revision: 1.5
Committed: Tue Dec 30 15:48:38 2003 UTC (20 years, 4 months ago) by dl
Branch: MAIN
Changes since 1.4: +5 -13 lines
Log Message:
Avoid cache thrashing

File Contents

# Content
1 /*
2 * Written by Doug Lea with assistance from members of JCP JSR-166
3 * Expert Group and released to the public domain, as explained at
4 * http://creativecommons.org/licenses/publicdomain
5 * Other contributors include Andrew Wright, Jeffrey Hayes,
6 * Pat Fisher, Mike Judd.
7 */
8
9
10 import junit.framework.*;
11 import java.util.*;
12 import java.util.concurrent.*;
13 import java.util.concurrent.locks.*;
14 import java.io.*;
15
16 public class AbstractQueuedSynchronizerTest extends JSR166TestCase {
17 public static void main(String[] args) {
18 junit.textui.TestRunner.run (suite());
19 }
20 public static Test suite() {
21 return new TestSuite(AbstractQueuedSynchronizerTest.class);
22 }
23
24 /**
25 * A simple mutex class, from the AbstractQueuedSynchronizer
26 * javadoc. All tests exercise this as a sample user extension.
27 * Other methods/features of AbstractQueuedSynchronizerTest are
28 * tested implicitly in ReentrantLock, ReentrantReadWriteLock, and
29 * Semaphore test classes
30 */
31 static class Mutex implements Lock, java.io.Serializable {
32 private static class Sync extends AbstractQueuedSynchronizer {
33 public int acquireExclusiveState(boolean isQueued, int acquires) {
34 assert acquires == 1; // Does not use multiple acquires
35 return compareAndSet(0, 1)? 0 : -1;
36 }
37
38 public boolean releaseExclusiveState(int releases) {
39 set(0);
40 return true;
41 }
42
43 public void checkConditionAccess(Thread thread, boolean waiting) {
44 if (get() == 0) throw new IllegalMonitorStateException();
45 }
46
47 Condition newCondition() { return new ConditionObject(); }
48
49 private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
50 s.defaultReadObject();
51 set(0); // reset to unlocked state
52 }
53 }
54
55 private final Sync sync = new Sync();
56 public boolean tryLock() {
57 return sync.acquireExclusiveState(false, 1) >= 0;
58 }
59 public void lock() {
60 sync.acquireExclusiveUninterruptibly(1);
61 }
62 public void lockInterruptibly() throws InterruptedException {
63 sync.acquireExclusiveInterruptibly(1);
64 }
65 public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
66 return sync.acquireExclusiveTimed(1, unit.toNanos(timeout));
67 }
68 public void unlock() { sync.releaseExclusive(1); }
69 public Condition newCondition() { return sync.newCondition(); }
70 public boolean isLocked() { return sync.get() != 0; }
71 public boolean hasQueuedThreads() { return sync.hasQueuedThreads(); }
72 }
73
74 /**
75 * A runnable calling lockInterruptibly
76 */
77 class InterruptibleLockRunnable implements Runnable {
78 final Mutex lock;
79 InterruptibleLockRunnable(Mutex l) { lock = l; }
80 public void run() {
81 try {
82 lock.lockInterruptibly();
83 } catch(InterruptedException success){}
84 }
85 }
86
87
88 /**
89 * A runnable calling lockInterruptibly that expects to be
90 * interrupted
91 */
92 class InterruptedLockRunnable implements Runnable {
93 final Mutex lock;
94 InterruptedLockRunnable(Mutex l) { lock = l; }
95 public void run() {
96 try {
97 lock.lockInterruptibly();
98 threadShouldThrow();
99 } catch(InterruptedException success){}
100 }
101 }
102
103 /**
104 * locking an unlocked lock succeeds
105 */
106 public void testLock() {
107 Mutex rl = new Mutex();
108 rl.lock();
109 assertTrue(rl.isLocked());
110 rl.unlock();
111 }
112
113 /**
114 * tryLock on an unlocked lock succeeds
115 */
116 public void testTryLock() {
117 Mutex rl = new Mutex();
118 assertTrue(rl.tryLock());
119 assertTrue(rl.isLocked());
120 rl.unlock();
121 }
122
123 /**
124 * hasQueuedThreads reports whether there are waiting threads
125 */
126 public void testhasQueuedThreads() {
127 final Mutex lock = new Mutex();
128 Thread t1 = new Thread(new InterruptedLockRunnable(lock));
129 Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
130 try {
131 assertFalse(lock.hasQueuedThreads());
132 lock.lock();
133 t1.start();
134 Thread.sleep(SHORT_DELAY_MS);
135 assertTrue(lock.hasQueuedThreads());
136 t2.start();
137 Thread.sleep(SHORT_DELAY_MS);
138 assertTrue(lock.hasQueuedThreads());
139 t1.interrupt();
140 Thread.sleep(SHORT_DELAY_MS);
141 assertTrue(lock.hasQueuedThreads());
142 lock.unlock();
143 Thread.sleep(SHORT_DELAY_MS);
144 assertFalse(lock.hasQueuedThreads());
145 t1.join();
146 t2.join();
147 } catch(Exception e){
148 unexpectedException();
149 }
150 }
151
152 /**
153 * timed tryLock is interruptible.
154 */
155 public void testInterruptedException2() {
156 final Mutex lock = new Mutex();
157 lock.lock();
158 Thread t = new Thread(new Runnable() {
159 public void run() {
160 try {
161 lock.tryLock(MEDIUM_DELAY_MS,TimeUnit.MILLISECONDS);
162 threadShouldThrow();
163 } catch(InterruptedException success){}
164 }
165 });
166 try {
167 t.start();
168 t.interrupt();
169 } catch(Exception e){
170 unexpectedException();
171 }
172 }
173
174
175 /**
176 * TryLock on a locked lock fails
177 */
178 public void testTryLockWhenLocked() {
179 final Mutex lock = new Mutex();
180 lock.lock();
181 Thread t = new Thread(new Runnable() {
182 public void run() {
183 threadAssertFalse(lock.tryLock());
184 }
185 });
186 try {
187 t.start();
188 t.join();
189 lock.unlock();
190 } catch(Exception e){
191 unexpectedException();
192 }
193 }
194
195 /**
196 * Timed tryLock on a locked lock times out
197 */
198 public void testTryLock_Timeout() {
199 final Mutex lock = new Mutex();
200 lock.lock();
201 Thread t = new Thread(new Runnable() {
202 public void run() {
203 try {
204 threadAssertFalse(lock.tryLock(1, TimeUnit.MILLISECONDS));
205 } catch (Exception ex) {
206 threadUnexpectedException();
207 }
208 }
209 });
210 try {
211 t.start();
212 t.join();
213 lock.unlock();
214 } catch(Exception e){
215 unexpectedException();
216 }
217 }
218
219
220 /**
221 * isLocked is true when locked and false when not
222 */
223 public void testIsLocked() {
224 final Mutex lock = new Mutex();
225 lock.lock();
226 assertTrue(lock.isLocked());
227 lock.unlock();
228 assertFalse(lock.isLocked());
229 Thread t = new Thread(new Runnable() {
230 public void run() {
231 lock.lock();
232 try {
233 Thread.sleep(SMALL_DELAY_MS);
234 }
235 catch(Exception e) {
236 threadUnexpectedException();
237 }
238 lock.unlock();
239 }
240 });
241 try {
242 t.start();
243 Thread.sleep(SHORT_DELAY_MS);
244 assertTrue(lock.isLocked());
245 t.join();
246 assertFalse(lock.isLocked());
247 } catch(Exception e){
248 unexpectedException();
249 }
250 }
251
252
253 /**
254 * lockInterruptibly is interruptible.
255 */
256 public void testLockInterruptibly1() {
257 final Mutex lock = new Mutex();
258 lock.lock();
259 Thread t = new Thread(new InterruptedLockRunnable(lock));
260 try {
261 t.start();
262 t.interrupt();
263 lock.unlock();
264 t.join();
265 } catch(Exception e){
266 unexpectedException();
267 }
268 }
269
270 /**
271 * lockInterruptibly succeeds when unlocked, else is interruptible
272 */
273 public void testLockInterruptibly2() {
274 final Mutex lock = new Mutex();
275 try {
276 lock.lockInterruptibly();
277 } catch(Exception e) {
278 unexpectedException();
279 }
280 Thread t = new Thread(new InterruptedLockRunnable(lock));
281 try {
282 t.start();
283 t.interrupt();
284 assertTrue(lock.isLocked());
285 t.join();
286 } catch(Exception e){
287 unexpectedException();
288 }
289 }
290
291 /**
292 * Calling await without holding lock throws IllegalMonitorStateException
293 */
294 public void testAwait_IllegalMonitor() {
295 final Mutex lock = new Mutex();
296 final Condition c = lock.newCondition();
297 try {
298 c.await();
299 shouldThrow();
300 }
301 catch (IllegalMonitorStateException success) {
302 }
303 catch (Exception ex) {
304 unexpectedException();
305 }
306 }
307
308 /**
309 * Calling signal without holding lock throws IllegalMonitorStateException
310 */
311 public void testSignal_IllegalMonitor() {
312 final Mutex lock = new Mutex();
313 final Condition c = lock.newCondition();
314 try {
315 c.signal();
316 shouldThrow();
317 }
318 catch (IllegalMonitorStateException success) {
319 }
320 catch (Exception ex) {
321 unexpectedException();
322 }
323 }
324
325 /**
326 * awaitNanos without a signal times out
327 */
328 public void testAwaitNanos_Timeout() {
329 final Mutex lock = new Mutex();
330 final Condition c = lock.newCondition();
331 try {
332 lock.lock();
333 long t = c.awaitNanos(100);
334 assertTrue(t <= 0);
335 lock.unlock();
336 }
337 catch (Exception ex) {
338 unexpectedException();
339 }
340 }
341
342 /**
343 * timed await without a signal times out
344 */
345 public void testAwait_Timeout() {
346 final Mutex lock = new Mutex();
347 final Condition c = lock.newCondition();
348 try {
349 lock.lock();
350 assertFalse(c.await(SHORT_DELAY_MS, TimeUnit.MILLISECONDS));
351 lock.unlock();
352 }
353 catch (Exception ex) {
354 unexpectedException();
355 }
356 }
357
358 /**
359 * awaitUntil without a signal times out
360 */
361 public void testAwaitUntil_Timeout() {
362 final Mutex lock = new Mutex();
363 final Condition c = lock.newCondition();
364 try {
365 lock.lock();
366 java.util.Date d = new java.util.Date();
367 assertFalse(c.awaitUntil(new java.util.Date(d.getTime() + 10)));
368 lock.unlock();
369 }
370 catch (Exception ex) {
371 unexpectedException();
372 }
373 }
374
375 /**
376 * await returns when signalled
377 */
378 public void testAwait() {
379 final Mutex lock = new Mutex();
380 final Condition c = lock.newCondition();
381 Thread t = new Thread(new Runnable() {
382 public void run() {
383 try {
384 lock.lock();
385 c.await();
386 lock.unlock();
387 }
388 catch(InterruptedException e) {
389 threadUnexpectedException();
390 }
391 }
392 });
393
394 try {
395 t.start();
396 Thread.sleep(SHORT_DELAY_MS);
397 lock.lock();
398 c.signal();
399 lock.unlock();
400 t.join(SHORT_DELAY_MS);
401 assertFalse(t.isAlive());
402 }
403 catch (Exception ex) {
404 unexpectedException();
405 }
406 }
407
408 }