ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/AbstractQueuedSynchronizerTest.java
Revision: 1.1
Committed: Sun Dec 28 21:56:18 2003 UTC (20 years, 4 months ago) by dl
Branch: MAIN
Log Message:
Add tests for AQS extensions; adjust others for protected condition methods

File Contents

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