KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sleepycat > je > latch > LatchTest


1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2002,2006 Oracle. All rights reserved.
5  *
6  * $Id: LatchTest.java,v 1.33 2006/10/30 21:14:46 bostic Exp $
7  */

8
9 package com.sleepycat.je.latch;
10
11 import junit.framework.TestCase;
12
13 import com.sleepycat.je.DatabaseException;
14 import com.sleepycat.je.junit.JUnitThread;
15
16 public class LatchTest extends TestCase {
17     private Latch latch1 = null;
18     private Latch latch2 = null;
19     private JUnitThread tester1 = null;
20     private JUnitThread tester2 = null;
21     
22     static private final boolean DEBUG = false;
23
24     private void debugMsg(String JavaDoc message) {
25     if (DEBUG) {
26         System.out.println(Thread.currentThread().toString()
27                    + " " + message);
28     }
29     }
30
31     public void setUp() {
32     }
33
34     private void initExclusiveLatches() {
35     latch1 = LatchSupport.makeLatch("LatchTest-latch1", null);
36     latch2 = LatchSupport.makeLatch("LatchTest-latch2", null);
37     }
38
39     public void tearDown() {
40     latch1 = null;
41     latch2 = null;
42     }
43
44     public void testAcquireAndReacquire()
45     throws Throwable JavaDoc {
46
47     initExclusiveLatches();
48     JUnitThread tester =
49         new JUnitThread("testAcquireAndReacquire") {
50         public void testBody() {
51             /* Acquire a latch. */
52             try {
53             latch1.acquire();
54             } catch (DatabaseException LE) {
55             fail("caught DatabaseException");
56             }
57
58             /* Try to acquire it again -- should fail. */
59             try {
60             latch1.acquire();
61             fail("didn't catch LatchException");
62             } catch (LatchException LE) {
63             assertTrue
64                 (latch1.getLatchStats().nAcquiresSelfOwned == 1);
65             } catch (DatabaseException DE) {
66             fail("didn't catch LatchException-caught DE instead");
67             }
68
69             /* Release it. */
70             try {
71             latch1.release();
72             } catch (LatchNotHeldException LNHE) {
73             fail("unexpected LatchNotHeldException");
74             }
75
76             /* Release it again -- should fail. */
77             try {
78             latch1.release();
79             fail("didn't catch LatchNotHeldException");
80             } catch (LatchNotHeldException LNHE) {
81             }
82         }
83         };
84
85     tester.doTest();
86     }
87
88     public void testAcquireAndReacquireShared()
89     throws Throwable JavaDoc {
90
91     final SharedLatch latch =
92         LatchSupport.makeSharedLatch("LatchTest-latch2", null);
93
94     JUnitThread tester =
95         new JUnitThread("testAcquireAndReacquireShared") {
96         public void testBody() {
97             /* Acquire a shared latch. */
98             try {
99             latch.acquireShared();
100             } catch (DatabaseException LE) {
101             fail("caught DatabaseException");
102             }
103
104             assert latch.isOwner();
105
106             /* Try to acquire it again -- should succeed. */
107             try {
108             latch.acquireShared();
109             } catch (LatchException LE) {
110             fail("didn't catch LatchException");
111             } catch (DatabaseException DE) {
112             fail("didn't catch LatchException-caught DE instead");
113             }
114
115             assert latch.isOwner();
116
117             /* Release it. */
118             try {
119             latch.release();
120             } catch (LatchNotHeldException LNHE) {
121             fail("unexpected LatchNotHeldException");
122             }
123
124             /* Release it again -- should succeed. */
125             try {
126             latch.release();
127             } catch (LatchNotHeldException LNHE) {
128             fail("didn't catch LatchNotHeldException");
129             }
130
131             /* Release it again -- should fail. */
132             try {
133             latch.release();
134             fail("didn't catch LatchNotHeldException");
135             } catch (LatchNotHeldException LNHE) {
136             }
137         }
138         };
139
140     tester.doTest();
141     }
142
143     /*
144      * Do a million acquire/release pairs. The junit output will tell us how
145      * long it took.
146      */

147     public void testAcquireReleasePerformance()
148     throws Throwable JavaDoc {
149
150     initExclusiveLatches();
151     JUnitThread tester =
152         new JUnitThread("testAcquireReleasePerformance") {
153         public void testBody() {
154             final int N_PERF_TESTS = 1000000;
155             for (int i = 0; i < N_PERF_TESTS; i++) {
156             /* Acquire a latch */
157             try {
158                 latch1.acquire();
159             } catch (DatabaseException LE) {
160                 fail("caught DatabaseException");
161             }
162
163             /* Release it. */
164             try {
165                 latch1.release();
166             } catch (LatchNotHeldException LNHE) {
167                 fail("unexpected LatchNotHeldException");
168             }
169             }
170             LatchStats stats = latch1.getLatchStats();
171             assertTrue(stats.nAcquiresNoWaiters == N_PERF_TESTS);
172             assertTrue(stats.nReleases == N_PERF_TESTS);
173         }
174         };
175
176     tester.doTest();
177     }
178
179     /* Test latch waiting. */
180
181     public void testWait()
182     throws Throwable JavaDoc {
183
184     initExclusiveLatches();
185     for (int i = 0; i < 10; i++) {
186         doTestWait();
187     }
188     }
189
190     private int nAcquiresWithContention = 0;
191
192     public void doTestWait()
193     throws Throwable JavaDoc {
194
195     tester1 =
196         new JUnitThread("testWait-Thread1") {
197         public void testBody() {
198             /* Acquire a latch. */
199             try {
200             latch1.acquire();
201             } catch (DatabaseException LE) {
202             fail("caught DatabaseException");
203             }
204
205             /* Wait for tester2 to try to acquire the latch. */
206             while (latch1.nWaiters() == 0) {
207             Thread.yield();
208             }
209
210             try {
211             latch1.release();
212             } catch (LatchNotHeldException LNHE) {
213             fail("unexpected LatchNotHeldException");
214             }
215         }
216         };
217
218     tester2 =
219         new JUnitThread("testWait-Thread2") {
220         public void testBody() {
221             /* Wait for tester1 to start. */
222
223             while (latch1.owner() != tester1) {
224             Thread.yield();
225             }
226
227             /* Acquire a latch. */
228             try {
229             latch1.acquire();
230             } catch (DatabaseException LE) {
231             fail("caught DatabaseException");
232             }
233
234             assertTrue(latch1.getLatchStats().nAcquiresWithContention
235                    == ++nAcquiresWithContention);
236
237             /* Release it. */
238             try {
239             latch1.release();
240             } catch (LatchNotHeldException LNHE) {
241             fail("unexpected LatchNotHeldException");
242             }
243         }
244         };
245
246     tester1.start();
247     tester2.start();
248     tester1.finishTest();
249     tester2.finishTest();
250     }
251
252     /* Test acquireNoWait(). */
253
254     private volatile boolean attemptedAcquireNoWait;
255
256     public void testAcquireNoWait()
257     throws Throwable JavaDoc {
258
259     initExclusiveLatches();
260     tester1 =
261         new JUnitThread("testWait-Thread1") {
262         public void testBody() {
263             debugMsg("Acquiring Latch");
264             /* Acquire a latch. */
265             try {
266             latch1.acquire();
267             } catch (DatabaseException LE) {
268             fail("caught DatabaseException");
269             }
270
271             /* Wait for tester2 to try to acquire the latch. */
272
273             debugMsg("Waiting for other thread");
274             while (!attemptedAcquireNoWait) {
275             Thread.yield();
276             }
277
278             debugMsg("Releasing the latch");
279             try {
280             latch1.release();
281             } catch (LatchNotHeldException LNHE) {
282             fail("unexpected LatchNotHeldException");
283             }
284         }
285         };
286
287     tester2 =
288         new JUnitThread("testWait-Thread2") {
289         public void testBody() {
290             /* Wait for tester1 to start. */
291
292             debugMsg("Waiting for T1 to acquire latch");
293             while (latch1.owner() != tester1) {
294             Thread.yield();
295             }
296
297             /*
298              * Attempt Acquire with no wait -- should fail since
299              * tester1 has it.
300              */

301             debugMsg("Acquiring no wait");
302             try {
303             assertFalse(latch1.acquireNoWait());
304             assertTrue(latch1.getLatchStats().
305                    nAcquireNoWaitUnsuccessful == 1);
306             } catch (DatabaseException LE) {
307             fail("caught DatabaseException");
308             }
309
310             attemptedAcquireNoWait = true;
311
312             debugMsg("Waiting for T1 to release latch");
313             while (latch1.owner() != null) {
314             Thread.yield();
315             }
316
317             /*
318              * Attempt Acquire with no wait -- should succeed now that
319              * tester1 is done.
320              */

321             debugMsg("Acquiring no wait - 2");
322             try {
323             assertTrue(latch1.acquireNoWait());
324             assertTrue(latch1.getLatchStats().
325                    nAcquireNoWaitSuccessful == 1);
326             } catch (DatabaseException LE) {
327             fail("caught DatabaseException");
328             }
329
330             /*
331              * Attempt Acquire with no wait again -- should throw
332              * exception since we already have it.
333              */

334             debugMsg("Acquiring no wait - 3");
335             try {
336             latch1.acquireNoWait();
337             fail("didn't throw LatchException");
338             } catch (LatchException LE) {
339                 // expected
340
} catch (Exception JavaDoc e) {
341             fail("caught Exception");
342             }
343
344             /* Release it. */
345             debugMsg("releasing the latch");
346             try {
347             latch1.release();
348             } catch (LatchNotHeldException LNHE) {
349             fail("unexpected LatchNotHeldException");
350             }
351         }
352         };
353
354     tester1.start();
355     tester2.start();
356     tester1.finishTest();
357     tester2.finishTest();
358     }
359
360     /* State for testMultipleWaiters. */
361     private final int N_WAITERS = 5;
362
363     /* A JUnitThread that holds the waiter number. */
364     private class MultiWaiterTestThread extends JUnitThread {
365     private int waiterNumber;
366     public MultiWaiterTestThread(String JavaDoc name, int waiterNumber) {
367         super(name);
368         this.waiterNumber = waiterNumber;
369     }
370     }
371
372     public void testMultipleWaiters()
373     throws Throwable JavaDoc {
374
375     initExclusiveLatches();
376     JUnitThread[] waiterThreads =
377         new JUnitThread[N_WAITERS];
378
379     tester1 =
380         new JUnitThread("testWait-Thread1") {
381         public void testBody() {
382
383             debugMsg("About to acquire latch");
384
385             /* Acquire a latch. */
386             try {
387             latch1.acquire();
388             } catch (DatabaseException LE) {
389             fail("caught DatabaseException");
390             }
391
392             debugMsg("acquired latch");
393
394             /*
395              * Wait for all other testers to be waiting on the latch.
396              */

397             while (latch1.nWaiters() < N_WAITERS) {
398             Thread.yield();
399             }
400
401             debugMsg("About to release latch");
402
403             try {
404             latch1.release();
405             } catch (LatchNotHeldException LNHE) {
406             fail("unexpected LatchNotHeldException");
407             }
408         }
409         };
410
411     for (int i = 0; i < N_WAITERS; i++) {
412         waiterThreads[i] =
413         new MultiWaiterTestThread("testWait-Waiter" + i, i) {
414             public void testBody() {
415
416             int waiterNumber =
417                 ((MultiWaiterTestThread)
418                  Thread.currentThread()).waiterNumber;
419
420             /* Wait for tester1 to start. */
421             debugMsg("Waiting for main to acquire latch");
422
423             while (latch1.owner() != tester1) {
424                 Thread.yield();
425             }
426
427             /*
428              * Wait until it's our turn to try to acquire the
429              * latch.
430              */

431             debugMsg("Waiting for our turn to acquire latch");
432             while (latch1.nWaiters() < waiterNumber) {
433                 Thread.yield();
434             }
435
436             debugMsg("About to acquire latch");
437             /* Try to acquire the latch */
438             try {
439                 latch1.acquire();
440             } catch (DatabaseException LE) {
441                 fail("caught DatabaseException");
442             }
443
444             debugMsg("nWaiters: " + latch1.nWaiters());
445             assertTrue(latch1.nWaiters() ==
446                    (N_WAITERS - waiterNumber - 1));
447
448             debugMsg("About to release latch");
449             /* Release it. */
450             try {
451                 latch1.release();
452             } catch (LatchNotHeldException LNHE) {
453                 fail("unexpected LatchNotHeldException");
454             }
455             }
456         };
457     }
458
459     tester1.start();
460
461     for (int i = 0; i < N_WAITERS; i++) {
462         waiterThreads[i].start();
463     }
464
465     tester1.finishTest();
466     for (int i = 0; i < N_WAITERS; i++) {
467         waiterThreads[i].finishTest();
468     }
469     }
470 }
471
Popular Tags