KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > cache > lock > ReadWriteLockWithUpgradeTest


1 package org.jboss.cache.lock;
2
3 import junit.framework.Test;
4 import junit.framework.TestCase;
5 import junit.framework.TestSuite;
6 import org.jboss.cache.misc.TestingUtil;
7
8 import java.io.FileWriter JavaDoc;
9 import java.io.IOException JavaDoc;
10 import java.io.Writer JavaDoc;
11 import java.util.Vector JavaDoc;
12 import java.util.concurrent.TimeUnit JavaDoc;
13 import java.util.concurrent.locks.Lock JavaDoc;
14
15 /**
16  * NonBlockingWriterLock is a read/write lock (with upgrade) that has
17  * non-blocking write lock acquisition on existing read lock(s).
18  * <p>Note that the write lock is exclusive among write locks, e.g.,
19  * only one write lock can be granted at one time, but the write lock
20  * is independent of the read locks. For example,
21  * a read lock to be acquired will be blocked if there is existing write lock, but
22  * will not be blocked if there are mutiple read locks already granted to other
23  * owners. On the other hand, a write lock can be acquired as long as there
24  * is no existing write lock, regardless how many read locks have been
25  * granted.
26  *
27  * @author <a HREF="mailto:cavin_song@yahoo.com">Cavin Song</a> April 22, 2004
28  * @version 1.0
29  */

30 public class ReadWriteLockWithUpgradeTest extends TestCase
31 {
32    static final ReadWriteLockWithUpgrade lock_ = new ReadWriteLockWithUpgrade();
33    static long SLEEP_MSECS = 500;
34    Vector JavaDoc lockResult = new Vector JavaDoc();
35    int NO_MORE_OP = 0;
36    int INVOKE_READ = 1;
37    int INVOKE_WRITE = 2;
38    int INVOKE_UPGRADE = 3;
39
40    public ReadWriteLockWithUpgradeTest(String JavaDoc name)
41    {
42       super(name);
43    }
44
45
46    public static void main(String JavaDoc[] args) throws Exception JavaDoc
47    {
48       log("\nBeginning ReadWriteLockWithUpgrade automated testing ...\n");
49
50       junit.textui.TestRunner.run(suite());
51    }
52
53    // Needed for JUnit.
54
public static Test suite()
55    {
56       TestSuite suite = new TestSuite();
57       // Adding test cases here ...
58
suite.addTestSuite(ReadWriteLockWithUpgradeTest.class);
59       return suite;
60    }
61
62    public void setUp()
63    {
64       logX("\n");
65       log("Setting up test case ...");
66    }
67
68    public void tearDown()
69    {
70       log("Tearing down test case ...");
71    }
72
73    public static void log(String JavaDoc str)
74    {
75       System.out.println(Thread.currentThread() + ": "
76               + java.util.Calendar.getInstance().getTime() + " : " + str);
77    }
78
79    // For debugging purpose
80
public static void logX(String JavaDoc str)
81    {
82       log(str);
83       // try {
84
// logToFile(str);
85
// } catch (IOException ioe) {
86
// }
87
}
88
89    // Debugging intrnal function
90
public static void logToFile(String JavaDoc str) throws IOException JavaDoc
91    {
92       Writer JavaDoc out = new FileWriter JavaDoc("./RepeatableLogs.txt", true/*append*/);
93       out.write(str);
94       out.close();
95    }
96
97    /***************************************************************/
98    /* Utility functions to creat threads for RL, WL and UL */
99    /***************************************************************/
100    /**
101     * Creates a new thread and acquires a read lock with a timeout
102     * value specified by the caller. Optionally, the caller can request
103     * a second read or write lock after the first read lock request.
104     * The locking result is stored in a vector with the following
105     * format:
106     * <p><DL>
107     * <DD>'case number'-'thread name'-[RL|WL|UL]-[0|1]
108     * </DL>
109     * <p>where:
110     * <DL>
111     * <DD> 'case number' is the passed in test case # by the caller.
112     * <DD> 'thread name' is the passed in thread name by the caller.
113     * <DD> RL - indicating was doing read lock request.
114     * <DD> WL - indicating was doing write lock request.
115     * <DD> UL - indicating was doing upgrade lock request.
116     * <DD> 0 - indicating the locking request failed.
117     * <DD> 1 - indicating the locking request succeeded.
118     * </DL>
119     * <p/>
120     * After all threads in each test case terminate, the test case
121     * should make the following call to verify the test result:
122     * <DL>
123     * <DD> asssertTrue(checkLockingResult(expected-result-string);
124     * </DL>
125     * <p/>
126     * 'expected-result-string' is the locking result string
127     * described above. For example, "8-t1-RL-0" means that thread
128     * t1 in test case #8 doing a Read Lock request expects the
129     * operation to fail. If the expected result string can't be
130     * found then the test case is considered FAILED (ie, either
131     * the read lock request was successful or did not complete).
132     * <p/>
133     * Each test case should also call cleanLockingResult() to reset
134     * result vector for the next test cases.
135     *
136     * @param caseNum Arbitrary string for the test case number.
137     * @param name Arbitrary string for the calling thread name.
138     * @param msecs Milliseconds that the thread should sleep after
139     * acquiring the read lock.
140     * @param errMsg Error msg to log in case of error.
141     * @param secondOP Set to NO_MORE_OP if a 2nd lock request is not required.
142     * Set to INVOKE_READ, INVOKE_READ or INVOKE_UPGRADE
143     * respectively if the 2nd lock is a read, write or
144     * upgrade request respectively.
145     */

146
147    protected Thread JavaDoc readThread(final String JavaDoc caseNum, final String JavaDoc name,
148                                final long msecs, final long sleepSecs,
149                                final String JavaDoc errMsg, final int secondOP)
150    {
151       return new Thread JavaDoc(name)
152       {
153          public void run()
154          {
155             Lock JavaDoc rlock = lock_.readLock();
156             try
157             {
158                if (!rlock.tryLock(msecs, TimeUnit.MILLISECONDS))
159                {
160                   logX(caseNum + "-" + name + " requesting read lock failed!\n");
161                   String JavaDoc str = caseNum + "-" + name + "-RL-0";
162                   postLockingResult(str);
163                   return;
164                }
165                // OK, read lock obtained, sleep and release it.
166
logX(caseNum + "-" + name + " requesting read lock succeeded!\n");
167                String JavaDoc str = caseNum + "-" + name + "-RL-1";
168                postLockingResult(str);
169                TestingUtil.sleepThread(sleepSecs);
170
171                if (secondOP == INVOKE_READ)
172                {
173                   acquireReadLock(caseNum, name, msecs, errMsg);
174                }
175                else if (secondOP == INVOKE_WRITE)
176                {
177                   acquireWriteLock(caseNum, name, msecs, errMsg);
178                }
179                else if (secondOP == INVOKE_UPGRADE)
180                {
181                   acquireUpgradeLock(caseNum, name, msecs, errMsg);
182                }
183
184                rlock.unlock();
185                logX(caseNum + "-" + name + " releasing read lock.\n");
186             }
187             catch (Exception JavaDoc ex)
188             {
189             }
190          }
191       };
192    }
193
194    /**
195     * Creates a new thread and acquires a write lock with a timeout
196     * value specified by the caller. Similar to {@link #readThread readThread()}
197     * except it's used for write locks.
198     *
199     * @see #readThread readThread()
200     */

201    protected Thread JavaDoc writeThread(final String JavaDoc caseNum, final String JavaDoc name,
202                                 final long msecs, final long sleepSecs,
203                                 final String JavaDoc errMsg, final int secondOP)
204    {
205       return new Thread JavaDoc(name)
206       {
207          public void run()
208          {
209             try
210             {
211                Lock JavaDoc wlock = lock_.writeLock();
212                if (!wlock.tryLock(msecs, TimeUnit.MILLISECONDS))
213                {
214                   logX(caseNum + "-" + name + " requesting write lock failed!\n");
215                   String JavaDoc str = caseNum + "-" + name + "-WL-0";
216                   postLockingResult(str);
217                   return;
218                }
219                // OK, write lock obtained, sleep and release it.
220
logX(caseNum + "-" + name + " requesting write lock succeeded!\n");
221                String JavaDoc str = caseNum + "-" + name + "-WL-1";
222                postLockingResult(str);
223                TestingUtil.sleepThread(sleepSecs);
224
225                if (secondOP == INVOKE_READ)
226                {
227                   acquireReadLock(caseNum, name, msecs, errMsg);
228                }
229                else if (secondOP == INVOKE_WRITE)
230                {
231                   acquireWriteLock(caseNum, name, msecs, errMsg);
232                }
233                else if (secondOP == INVOKE_UPGRADE)
234                {
235                   acquireUpgradeLock(caseNum, name, msecs, errMsg);
236                }
237
238                wlock.unlock();
239                logX(caseNum + "-" + name + " releasing write lock.\n");
240             }
241             catch (Exception JavaDoc ex)
242             {
243             }
244          }
245       };
246    }
247
248    /**
249     * Creates a new thread, acquires a read lock, sleeps for a while
250     * and then tries to upgrade the read lock to a write one. Similar
251     * to {@link #readThread readThread()} except it's used for upgrading
252     * locks.
253     *
254     * @see #readThread readThread()
255     */

256    protected Thread JavaDoc upgradeThread(final String JavaDoc caseNum, final String JavaDoc name,
257                                   final long msecs, final String JavaDoc errMsg)
258    {
259       return new Thread JavaDoc(name)
260       {
261          public void run()
262          {
263             try
264             {
265                Lock JavaDoc rlock = lock_.readLock();
266                Lock JavaDoc wlock = null;
267                if (!rlock.tryLock(msecs, TimeUnit.MILLISECONDS))
268                {
269                   logX(caseNum + "-" + name + " requesting read lock failed!\n");
270                   String JavaDoc str = caseNum + "-" + name + "-RL-0";
271                   postLockingResult(str);
272                   return;
273                }
274                // OK, read lock obtained, sleep and upgrade it later.
275
logX(caseNum + "-" + name + " requesting read lock succeeded (upgrade later)!\n");
276                TestingUtil.sleepThread(SLEEP_MSECS / 2);
277                String JavaDoc str = caseNum + "-" + name + "-UL-";
278                if ((wlock = lock_.upgradeLockAttempt(msecs)) == null)
279                {
280                   logX(caseNum + "-" + name + " requesting upgrade lock failed!\n");
281                   str += "0";
282                }
283                else
284                {
285                   logX(caseNum + "-" + name + " requesting upgrade lock succeeded!\n");
286                   str += "1";
287                }
288                postLockingResult(str);
289                // Sleep again and then release the lock.
290
TestingUtil.sleepThread(SLEEP_MSECS);
291                if (wlock != null)
292                {
293                   wlock.unlock();
294                   logX(caseNum + "-" + name + " releasing upgrade lock.\n");
295                }
296                rlock.unlock();
297             }
298             catch (Exception JavaDoc ex)
299             {
300             }
301          }
302       };
303    }
304
305    /***************************************************************/
306    /* Utility functions to acquire RL and WL (no thread) */
307    /***************************************************************/
308    /**
309     * This routine tries to acquire a read lock with a timeout value
310     * passed in by the caller. Like {@link #readThread readThread()}
311     * it then stores the locking result in the result vector depending
312     * on the outcome of the request.
313     */

314
315    protected void acquireReadLock(final String JavaDoc caseNum, final String JavaDoc name,
316                                   final long msecs, final String JavaDoc errMsg)
317    {
318       try
319       {
320          Lock JavaDoc rlock = lock_.readLock();
321          if (!rlock.tryLock(msecs, TimeUnit.MILLISECONDS))
322          {
323             logX(caseNum + "-" + name + " requesting read lock failed!\n");
324             String JavaDoc str = caseNum + "-" + name + "-RL-0";
325             postLockingResult(str);
326             return;
327          }
328          // OK, read lock obtained, sleep and release it.
329
logX(caseNum + "-" + name + " requesting read lock succeeded!\n");
330          String JavaDoc str = caseNum + "-" + name + "-RL-1";
331          postLockingResult(str);
332          TestingUtil.sleepThread(SLEEP_MSECS);
333          rlock.unlock();
334          logX(caseNum + "-" + name + " releasing read lock.\n");
335       }
336       catch (Exception JavaDoc ex)
337       {
338       }
339    }
340
341    /**
342     * Same as {@link #acquireReadLock acquireReadLock()} except
343     * it's for write lock request.
344     */

345    protected void acquireWriteLock(final String JavaDoc caseNum, final String JavaDoc name,
346                                    final long msecs, final String JavaDoc errMsg)
347    {
348       try
349       {
350          Lock JavaDoc wlock = lock_.writeLock();
351          if (!wlock.tryLock(msecs, TimeUnit.MILLISECONDS))
352          {
353             logX(caseNum + "-" + name + " requesting write lock failed!\n");
354             String JavaDoc str = caseNum + "-" + name + "-WL-0";
355             postLockingResult(str);
356             return;
357          }
358          // OK, write lock obtained, sleep and release it.
359
logX(caseNum + "-" + name + " requesting write lock succeeded!\n");
360          String JavaDoc str = caseNum + "-" + name + "-WL-1";
361          postLockingResult(str);
362          TestingUtil.sleepThread(SLEEP_MSECS);
363          wlock.unlock();
364          logX(caseNum + "-" + name + " releasing write lock.\n");
365       }
366       catch (Exception JavaDoc ex)
367       {
368       }
369    }
370
371    /**
372     * Same as {@link #acquireReadLock acquireReadLock()} except
373     * it's for upgrade lock request.
374     */

375    protected void acquireUpgradeLock(final String JavaDoc caseNum, final String JavaDoc name,
376                                      final long msecs, final String JavaDoc errMsg)
377    {
378       try
379       {
380          Lock JavaDoc ulock = null;
381          if ((ulock = lock_.upgradeLockAttempt(msecs)) == null)
382          {
383             logX(caseNum + "-" + name + " requesting upgrade lock failed!\n");
384             String JavaDoc str = caseNum + "-" + name + "-UL-0";
385             postLockingResult(str);
386             return;
387          }
388          // OK, write lock obtained, sleep and release it.
389
logX(caseNum + "-" + name + " requesting upgrade lock succeeded!\n");
390          String JavaDoc str = caseNum + "-" + name + "-UL-1";
391          postLockingResult(str);
392          TestingUtil.sleepThread(SLEEP_MSECS);
393          ulock.unlock();
394          logX(caseNum + "-" + name + " releasing upgrade lock.\n");
395       }
396       catch (Exception JavaDoc ex)
397       {
398       }
399    }
400
401    /***************************************************************/
402    /* Synchronized methods handling locking result vector */
403    /***************************************************************/
404    /**
405     * Clean/remove all locking results in the vector.
406     */

407    protected synchronized void cleanLockingResult()
408    {
409       lockResult.removeAllElements();
410    }
411
412    /**
413     * Post a locking result to the vector for later verification.
414     */

415    protected synchronized void postLockingResult(Object JavaDoc obj)
416    {
417       logX(" Added *" + obj + "* to the result vector\n");
418       // Make sure we only have one in the vector
419
//if (!checkLockingResult((String)obj))
420
lockResult.addElement(obj);
421    }
422
423    /**
424     * Check if a given expected locking result is in the vector.
425     */

426    protected synchronized boolean checkLockingResult(String JavaDoc expected)
427    {
428       boolean rc = false;
429       for (int i = 0; i < lockResult.size(); i++)
430       {
431          Object JavaDoc ele = lockResult.elementAt(i);
432          String JavaDoc str = (String JavaDoc) ele;
433          if (expected.equals(str))
434          {
435             rc = true;
436             break;
437          }
438       }
439       if (rc)
440       {
441          logX(" Searching for *" + expected + "* SUCCEEDED.\n");
442       }
443       else
444       {
445          logX(" Searching for *" + expected + "* FAILED.\n");
446       }
447       return rc;
448    }
449
450    /***************************************************************/
451    /* T e s t C a s e s */
452    /***************************************************************/
453    /**
454     * Case #10 - T1 acquires RL, T2 acquires RL followed by WL.
455     */

456    public void testWriteWithMultipleReaders() throws Exception JavaDoc
457    {
458       String JavaDoc caseNum = "10";
459       Thread JavaDoc t1 = readThread(caseNum, "t1", 0, SLEEP_MSECS * 2,
460               "1st read lock attempt failed", NO_MORE_OP);
461       Thread JavaDoc t2 = readThread(caseNum, "t2", 0, SLEEP_MSECS,
462               "2nd read lock attempt failed", INVOKE_WRITE);
463
464       t1.start();
465       t2.start();
466       t1.join(3000);
467       t2.join(3000);
468       assertTrue(checkLockingResult(caseNum + "-t1-RL-1") &&
469               checkLockingResult(caseNum + "-t2-RL-1") &&
470               checkLockingResult(caseNum + "-t2-WL-0"));
471       cleanLockingResult();
472       // possilbe deadlock check
473
if (t1.isAlive() || t2.isAlive())
474       {
475          fail("Possible deadlock resulted in testRead.");
476       }
477    }
478
479    /**
480     * Case #11 - T1 acquires RL followed by WL, T2 acquires RL.
481     */

482    public void testUpgradeWithMultipleReadersOn1() throws Exception JavaDoc
483    {
484       String JavaDoc caseNum = "11";
485       Thread JavaDoc t1 = readThread(caseNum, "t1", 0, SLEEP_MSECS,
486               "1st read lock attempt failed", INVOKE_WRITE);
487       Thread JavaDoc t2 = readThread(caseNum, "t2", 0, SLEEP_MSECS * 2,
488               "2nd read lock attempt failed", NO_MORE_OP);
489
490       t1.start();
491       t2.start();
492       t1.join(3000);
493       t2.join(3000);
494       assertTrue(checkLockingResult(caseNum + "-t1-RL-1") &&
495               checkLockingResult(caseNum + "-t2-RL-1") &&
496               checkLockingResult(caseNum + "-t1-WL-0"));
497       cleanLockingResult();
498       // possilbe deadlock check
499
if (t1.isAlive() || t2.isAlive())
500       {
501          fail("Possible deadlock resulted in testRead.");
502       }
503    }
504
505    /**
506     * Case #2 - T1 acquires RL followed by UL.
507     */

508    public void testUpgradeReadLock() throws Exception JavaDoc
509    {
510       String JavaDoc caseNum = "2";
511       Thread JavaDoc t1 = readThread(caseNum, "t1", 0, SLEEP_MSECS,
512               "1st read lock attempt failed", INVOKE_UPGRADE);
513
514       t1.start();
515       t1.join(3000);
516       assertTrue(checkLockingResult(caseNum + "-t1-RL-1") &&
517               checkLockingResult(caseNum + "-t1-UL-1"));
518       cleanLockingResult();
519    }
520
521    /**
522     * Case #3 - T1 acquires RL followed by WL.
523     */

524
525    public void testReadThenWrite() throws Exception JavaDoc
526    {
527       String JavaDoc caseNum = "3";
528       acquireReadLock(caseNum, "t1", 0, "1st read lock attempt failed");
529       acquireWriteLock(caseNum, "t1.1", 0, "2nd write lock attempt failed");
530       assertTrue(checkLockingResult(caseNum + "-t1-RL-1") &&
531               checkLockingResult(caseNum + "-t1.1-WL-1"));
532       cleanLockingResult();
533    }
534
535
536    /**
537     * Case #5 - T1 acquires WL followed by RL.
538     */

539
540    public void testWriteThenRead() throws Exception JavaDoc
541    {
542       String JavaDoc caseNum = "5";
543       acquireWriteLock(caseNum, "t1", 0, "1st write lock attempt failed");
544       acquireReadLock(caseNum, "t1.1", 0, "2nd read lock attempt failed");
545       assertTrue(checkLockingResult(caseNum + "-t1-WL-1") &&
546               checkLockingResult(caseNum + "-t1.1-RL-1"));
547       cleanLockingResult();
548    }
549
550    /**
551     * Case #6 - T1 acquires RL, T2 acquires RL.
552     */

553    public void testMultipleReadlock() throws Exception JavaDoc
554    {
555       String JavaDoc caseNum = "6";
556       Thread JavaDoc t1 = readThread(caseNum, "t1", 0, SLEEP_MSECS,
557               "1st read lock attempt failed", NO_MORE_OP);
558       Thread JavaDoc t2 = readThread(caseNum, "t2", 0, SLEEP_MSECS,
559               "2nd read lock attempt failed", NO_MORE_OP);
560
561       t1.start();
562       t2.start();
563       t1.join(3000);
564       t2.join(3000);
565       assertTrue(checkLockingResult(caseNum + "-t1-RL-1") &&
566               checkLockingResult(caseNum + "-t2-RL-1"));
567       cleanLockingResult();
568       // possilbe deadlock check
569
if (t1.isAlive() || t2.isAlive())
570       {
571          fail("Possible deadlock resulted in testRead.");
572       }
573    }
574
575    /**
576     * Case #8 - T1 acquires WL, T2 acquires RL.
577     */

578    public void testWriteWithExistingReader() throws Exception JavaDoc
579    {
580       String JavaDoc caseNum = "8";
581       Thread JavaDoc t1 = readThread(caseNum, "t1", 0, SLEEP_MSECS,
582               "1st write lock attempt failed", NO_MORE_OP);
583       Thread JavaDoc t2 = writeThread(caseNum, "t2", 0, SLEEP_MSECS,
584               "2nd read lock attempt failed", NO_MORE_OP);
585
586       t1.start();
587       t2.start();
588       t1.join(3000);
589       t2.join(3000);
590       assertTrue(checkLockingResult(caseNum + "-t1-RL-1") &&
591               checkLockingResult(caseNum + "-t2-WL-0"));
592       cleanLockingResult();
593       // possilbe deadlock check
594
if (t1.isAlive() || t2.isAlive())
595       {
596          fail("Possible deadlock resulted in testRead.");
597       }
598    }
599
600    /**
601     * Case #13 - T1 acquires RL, T2 acquires WL.
602     */

603    public void testReadWithExistingWriter() throws Exception JavaDoc
604    {
605       String JavaDoc caseNum = "13";
606       Thread JavaDoc t1 = writeThread(caseNum, "t1", 0, SLEEP_MSECS,
607               "1st write lock attempt failed", NO_MORE_OP);
608       Thread JavaDoc t2 = readThread(caseNum, "t2", 0, SLEEP_MSECS,
609               "2nd read lock attempt failed", NO_MORE_OP);
610
611       t1.start();
612       t2.start();
613       t1.join(3000);
614       t2.join(3000);
615       assertTrue(checkLockingResult(caseNum + "-t1-WL-1") &&
616               checkLockingResult(caseNum + "-t2-RL-0"));
617       cleanLockingResult();
618       // possilbe deadlock check
619
if (t1.isAlive() || t2.isAlive())
620       {
621          fail("Possible deadlock resulted in testRead.");
622       }
623    }
624
625    /**
626     * Case #14 - T1 acquires WL, T2 acquires WL.
627     */

628    public void testMultipleWritelocks() throws Exception JavaDoc
629    {
630       String JavaDoc caseNum = "14";
631       Thread JavaDoc t1 = writeThread(caseNum, "t1", 0, SLEEP_MSECS,
632               "1st write lock attempt failed", NO_MORE_OP);
633       Thread JavaDoc t2 = writeThread(caseNum, "t2", 0, SLEEP_MSECS,
634               "2nd write lock attempt failed", NO_MORE_OP);
635
636       t1.start();
637       t2.start();
638       t1.join(3000);
639       t2.join(3000);
640       assertTrue(checkLockingResult(caseNum + "-t1-WL-1") &&
641               checkLockingResult(caseNum + "-t2-WL-0"));
642       cleanLockingResult();
643       // possilbe deadlock check
644
if (t1.isAlive() || t2.isAlive())
645       {
646          fail("Possible deadlock resulted in testRead.");
647       }
648    }
649
650    /**
651     * Case #7 - T1 acquires RL, T2 acquires UL.
652     */

653
654    public void testUpgradeWithExistingReader() throws Exception JavaDoc
655    {
656       String JavaDoc caseNum = "7";
657       Thread JavaDoc t1 = readThread(caseNum, "t1", 0, SLEEP_MSECS,
658               "1st read lock attempt failed", NO_MORE_OP);
659       Thread JavaDoc t2 = upgradeThread(caseNum, "t2", 0,
660               "2nd upgrade lock attempt failed");
661
662       t1.start();
663       t2.start();
664       t1.join(3000);
665       t2.join(3000);
666       assertTrue(checkLockingResult(caseNum + "-t1-RL-1") &&
667               checkLockingResult(caseNum + "-t2-UL-0"));
668       cleanLockingResult();
669       // possilbe deadlock check
670
if (t1.isAlive() || t2.isAlive())
671       {
672          fail("Possible deadlock resulted in testRead.");
673       }
674    }
675
676    /**
677     * Case #9 - T1 acquires RL, T2 acquires RL followed by UL.
678     */

679    public void testUpgradeWithMultipleReaders() throws Exception JavaDoc
680    {
681       String JavaDoc caseNum = "9";
682       Thread JavaDoc t1 = readThread(caseNum, "t1", 0, SLEEP_MSECS * 2,
683               "1st read lock attempt failed", NO_MORE_OP);
684       Thread JavaDoc t2 = readThread(caseNum, "t2", 0, SLEEP_MSECS,
685               "2nd read lock attempt failed", INVOKE_UPGRADE);
686
687       t1.start();
688       t2.start();
689       t1.join(3000);
690       t2.join(3000);
691       assertTrue(checkLockingResult(caseNum + "-t1-RL-1") &&
692               checkLockingResult(caseNum + "-t2-RL-1") &&
693               checkLockingResult(caseNum + "-t2-UL-0"));
694       cleanLockingResult();
695       // possilbe deadlock check
696
if (t1.isAlive() || t2.isAlive())
697       {
698          fail("Possible deadlock resulted in testRead.");
699       }
700    }
701 }
702
703
Popular Tags