KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tctest > ReentrantLockTestApp


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
3  * notice. All rights reserved.
4  */

5 package com.tctest;
6
7 import com.tc.exception.TCNotSupportedMethodException;
8 import com.tc.exception.TCRuntimeException;
9 import com.tc.object.bytecode.ManagerUtil;
10 import com.tc.object.config.ConfigVisitor;
11 import com.tc.object.config.DSOClientConfigHelper;
12 import com.tc.object.config.TransparencyClassSpec;
13 import com.tc.object.lockmanager.api.LockLevel;
14 import com.tc.simulator.app.ApplicationConfig;
15 import com.tc.simulator.listener.ListenerProvider;
16 import com.tc.util.Assert;
17 import com.tctest.runner.AbstractTransparentApp;
18
19 import java.util.LinkedList JavaDoc;
20 import java.util.List JavaDoc;
21 import java.util.Random JavaDoc;
22 import java.util.concurrent.BrokenBarrierException JavaDoc;
23 import java.util.concurrent.CyclicBarrier JavaDoc;
24 import java.util.concurrent.TimeUnit JavaDoc;
25 import java.util.concurrent.locks.Condition JavaDoc;
26 import java.util.concurrent.locks.ReentrantLock JavaDoc;
27
28 public class ReentrantLockTestApp extends AbstractTransparentApp {
29   private static final int NUM_OF_PUTS = 100;
30   private static final int NUM_OF_LOOPS = 2;
31
32   private final DataRoot root = new DataRoot();
33   private final List JavaDoc queue = new LinkedList JavaDoc();
34   private final CyclicBarrier JavaDoc barrier2 = new CyclicBarrier JavaDoc(2);
35   private final CyclicBarrier JavaDoc barrier;
36
37   private final Random JavaDoc random;
38
39   private final ReentrantLock JavaDoc unsharedUnfairLock = new ReentrantLock JavaDoc();
40   private final ReentrantLock JavaDoc unsharedFairLock = new ReentrantLock JavaDoc(true);
41
42   private final Object JavaDoc testLockObject = new Object JavaDoc();
43
44   private int numOfPutters = 1;
45   private int numOfGetters;
46
47   public ReentrantLockTestApp(String JavaDoc appId, ApplicationConfig cfg, ListenerProvider listenerProvider) {
48     super(appId, cfg, listenerProvider);
49     barrier = new CyclicBarrier JavaDoc(getParticipantCount());
50     random = new Random JavaDoc(new Random JavaDoc(System.currentTimeMillis() + getApplicationId().hashCode()).nextLong());
51     numOfGetters = getParticipantCount() - numOfPutters;
52   }
53
54   public void run() {
55     try {
56       barrier.await();
57       
58       sharedUnSharedTesting();
59       multipleReentrantLocksTesting();
60       singleNodeTryBeginLockTesting();
61       variousLockUnLockPatternTesting();
62
63       for (int i = 0; i < NUM_OF_LOOPS; i++) {
64         basicConditionVariableTesting(root.getUnfairLock(), root.getUnfairCondition());
65         basicConditionVariableWaitTesting(root.getUnfairLock(), root.getUnfairCondition());
66       }
67
68       basicUnsharedLockTesting(unsharedUnfairLock);
69       for (int i = 0; i < NUM_OF_LOOPS; i++) {
70         basicLockTesting(root.getUnfairLock());
71         tryLockTimeoutTesting(root.getUnfairLock());
72       }
73       lockSyncLockTesting(root.getUnfairLock());
74       tryLockTesting(root.getUnfairLock());
75
76       threadInterruptedLockTesting(root.getUnfairLock());
77
78       for (int i = 0; i < NUM_OF_LOOPS; i++) {
79         basicConditionVariableTesting(root.getFairLock(), root.getFairCondition());
80         basicConditionVariableWaitTesting(root.getFairLock(), root.getFairCondition());
81       }
82       basicUnsharedLockTesting(unsharedFairLock);
83       for (int i = 0; i < NUM_OF_LOOPS; i++) {
84         basicLockTesting(root.getFairLock());
85         tryLockTimeoutTesting(root.getFairLock());
86       }
87       lockSyncLockTesting(root.getFairLock());
88       tryLockTesting(root.getFairLock());
89
90       threadInterruptedLockTesting(root.getFairLock());
91
92       barrier.await();
93     } catch (Throwable JavaDoc t) {
94       notifyError(t);
95     }
96   }
97
98   private void clear() throws Exception JavaDoc {
99     synchronized (root) {
100       if (root.getIndex() != 0) {
101         root.setIndex(0);
102       }
103     }
104
105     barrier.await();
106   }
107
108   private void sharedUnSharedTesting() throws Exception JavaDoc {
109
110     clear();
111
112     int index = -1;
113     synchronized (root) {
114       index = root.getIndex();
115       root.setIndex(index + 1);
116     }
117
118     barrier.await();
119
120     if (index == 0) {
121       ReentrantLock JavaDoc lock = new ReentrantLock JavaDoc();
122       Thread JavaDoc thread = new Thread JavaDoc(new TestRunnable2(lock));
123       lock.lock();
124       thread.start();
125       synchronized (root) {
126         root.setLazyLock(lock);
127       }
128     }
129
130     barrier.await();
131
132     if (index == 0) {
133       Assert.assertTrue(root.getLazyLock().isLocked());
134       root.getLazyLock().lock();
135     }
136
137     if (index == 0) {
138       root.getLazyLock().unlock();
139       root.getLazyLock().unlock();
140     }
141
142     barrier2.await();
143
144     barrier.await();
145
146     // Now, make sure another node can lock the lock.
147
if (index == 1) {
148       root.getLazyLock().lock();
149       root.getLazyLock().lock();
150     }
151
152     if (index == 1) {
153       root.getLazyLock().unlock();
154       root.getLazyLock().unlock();
155     }
156
157     barrier.await();
158
159     if (index == 1) {
160       Assert.assertFalse(root.getLazyLock().isLocked());
161     }
162
163     barrier.await();
164
165   }
166
167   /**
168    * This testcase is to ensure that the unlocking sequence can be different from the locking sequence. For example,
169    * lock1.lock(), lock2.lock(), lock1.unlock(), and lock2.unlock() as well as lock1.lock(), lock2.lock(),
170    * lock2.unlock(), lock1.unlock() will both work correctly.
171    */

172   private void multipleReentrantLocksTesting() throws Exception JavaDoc {
173     clear();
174
175     int index = -1;
176     synchronized (root) {
177       index = root.getIndex();
178       if (index == 0) {
179         root.setIndex(1);
180       } else if (index == 1) {
181         root.setIndex(2);
182       } else if (index == 2) {
183         root.setIndex(3);
184       }
185     }
186
187     barrier.await();
188
189     if (index == 0) {
190       root.getUnfairLock().lock();
191       root.getFairLock().lock();
192     }
193
194     barrier.await();
195
196     if (index == 0) {
197       Assert.assertTrue(root.getUnfairLock().isLocked());
198       Assert.assertTrue(root.getFairLock().isLocked());
199     }
200
201     barrier.await();
202
203     if (index == 0) {
204       root.getFairLock().unlock();
205     }
206
207     barrier.await();
208
209     if (index == 0) {
210       Assert.assertTrue(root.getUnfairLock().isLocked());
211       Assert.assertFalse(root.getFairLock().isLocked());
212     }
213
214     barrier.await();
215
216     if (index == 0) {
217       root.getUnfairLock().unlock();
218     }
219
220     barrier.await();
221
222     if (index == 0) {
223       Assert.assertFalse(root.getUnfairLock().isLocked());
224       Assert.assertFalse(root.getFairLock().isLocked());
225     }
226
227     barrier.await();
228
229     if (index == 1) {
230       root.getUnfairLock().lock();
231       root.getFairLock().lock();
232     }
233
234     barrier.await();
235
236     if (index == 1) {
237       Assert.assertTrue(root.getUnfairLock().isLocked());
238       Assert.assertTrue(root.getFairLock().isLocked());
239     }
240
241     barrier.await();
242
243     if (index == 1) {
244       root.getUnfairLock().unlock();
245     }
246
247     barrier.await();
248
249     if (index == 1) {
250       Assert.assertFalse(root.getUnfairLock().isLocked());
251       Assert.assertTrue(root.getFairLock().isLocked());
252     }
253
254     barrier.await();
255
256     if (index == 1) {
257       root.getFairLock().unlock();
258     }
259
260     barrier.await();
261
262     if (index == 1) {
263       Assert.assertFalse(root.getUnfairLock().isLocked());
264       Assert.assertFalse(root.getFairLock().isLocked());
265     }
266
267     barrier.await();
268   }
269
270   private void singleNodeTryBeginLockTesting() throws Exception JavaDoc {
271     clear();
272
273     int index = -1;
274     synchronized (root) {
275       index = root.getIndex();
276       if (index == 0) {
277         root.setIndex(1);
278       } else if (index == 1) {
279         root.setIndex(2);
280       } else if (index == 2) {
281         root.setIndex(3);
282       }
283     }
284
285     barrier.await();
286
287     if (index == 0) {
288       String JavaDoc lockId = "testLock";
289       CyclicBarrier JavaDoc localBarrier = new CyclicBarrier JavaDoc(2);
290       Thread JavaDoc thread1 = new Thread JavaDoc(new TestTryLockFailRunnable(lockId, localBarrier));
291
292       ManagerUtil.beginLock(lockId, LockLevel.WRITE);
293       thread1.start();
294       localBarrier.await();
295       ManagerUtil.commitLock(lockId);
296     }
297
298     barrier.await();
299   }
300
301   /**
302    * This testcase is to ensure that various lock and unlock sequence are functioned correctly. For example, lock() and
303    * unlock() method can be invoked within a synchronized block.
304    */

305   private void variousLockUnLockPatternTesting() throws Exception JavaDoc {
306     clear();
307
308     int index = -1;
309     synchronized (root) {
310       index = root.getIndex();
311       if (index == 0) {
312         root.setIndex(1);
313       } else if (index == 1) {
314         root.setIndex(2);
315       } else if (index == 2) {
316         root.setIndex(3);
317       }
318     }
319
320     barrier.await();
321
322     if (index == 0) {
323       root.getUnfairLock().lock();
324     }
325
326     barrier.await();
327
328     if (index == 0) {
329       Assert.assertTrue(root.getUnfairLock().isLocked());
330     }
331
332     barrier.await();
333
334     if (index == 0) {
335       synchronized (testLockObject) {
336         root.getUnfairLock().unlock();
337       }
338     }
339
340     barrier.await();
341
342     if (index == 0) {
343       Assert.assertFalse(root.getUnfairLock().isLocked());
344     }
345
346     barrier.await();
347
348     if (index == 1) {
349       root.getUnfairLock().lock();
350       synchronized (testLockObject) {
351         root.getUnfairLock().lock();
352       }
353     }
354
355     barrier.await();
356
357     if (index == 1) {
358       Assert.assertTrue(root.getUnfairLock().isLocked());
359     }
360
361     barrier.await();
362
363     if (index == 1) {
364       root.getUnfairLock().unlock();
365     }
366
367     barrier.await();
368
369     if (index == 1) {
370       Assert.assertTrue(root.getUnfairLock().isLocked());
371     }
372
373     barrier.await();
374
375     if (index == 1) {
376       root.getUnfairLock().unlock();
377     }
378
379     barrier.await();
380
381     /*
382      * Thread thread = new Thread(new TestRunnable3(root.getUnfairLock(), testLockObject)); if (index == 0) {
383      * thread.start(); } barrier.await(); if (index == 0) { Assert.assertTrue(root.getUnfairLock().isLocked()); }
384      * barrier.await(); if (index == 0) { thread.interrupt(); } barrier.await();
385      */

386   }
387
388   private void basicConditionVariableWaitTesting(ReentrantLock JavaDoc lock, Condition JavaDoc condition) throws Exception JavaDoc {
389     clear();
390
391     int index = -1;
392     synchronized (root) {
393       index = root.getIndex();
394       root.setIndex(index + 1);
395     }
396
397     barrier.await();
398
399     if (index == 0) {
400       Thread JavaDoc thread = new Thread JavaDoc(new TestRunnable1(lock, condition));
401       thread.start();
402     }
403
404     barrier.await();
405
406     if (index == 0) {
407       Thread.sleep(2000); // Sleep so that the TestRunnable1 thread can pick up.
408
Assert.assertEquals(1, lock.getWaitQueueLength(condition));
409     }
410
411     barrier.await();
412
413     if (index == 0) {
414       lock.lock();
415       try {
416         condition.signalAll();
417       } finally {
418         lock.unlock();
419       }
420     }
421
422     barrier.await();
423
424     if (index == 0) {
425       Assert.assertEquals(0, lock.getWaitQueueLength(condition));
426     }
427
428     barrier.await();
429   }
430
431   /**
432    * This test case tests the condition variable API. A condition variable is returned by called the newCondition()
433    * method of an reentrant lock.
434    */

435   private void basicConditionVariableTesting(ReentrantLock JavaDoc lock, Condition JavaDoc condition) throws Exception JavaDoc {
436     clear();
437
438     int index = -1;
439     synchronized (root) {
440       index = root.getIndex();
441       root.setIndex(index + 1);
442     }
443
444     barrier.await();
445     final long id = new Long JavaDoc(getApplicationId()).longValue();
446
447     if (index == 2) {
448       doPutter(id, lock, condition);
449     } else {
450       doGetter(id, lock, condition);
451     }
452
453     barrier.await();
454   }
455
456   private void doPutter(long id, ReentrantLock JavaDoc lock, Condition JavaDoc condition) throws Exception JavaDoc {
457     Thread.currentThread().setName("PUTTER-" + id);
458
459     for (int i = 0; i < NUM_OF_PUTS; i++) {
460       lock.lock();
461       try {
462         System.err.println("PUTTER-" + id + " Putting " + i);
463         queue.add(new WorkItem(String.valueOf(i)));
464         if (i % 2 == 0) {
465           condition.signalAll();
466         } else {
467           condition.signal();
468         }
469       } finally {
470         lock.unlock();
471       }
472     }
473
474     for (int i = 0; i < numOfGetters; i++) {
475       lock.lock();
476       try {
477         queue.add(WorkItem.STOP);
478         condition.signalAll();
479       } finally {
480         lock.unlock();
481       }
482     }
483   }
484
485   private void doGetter(long id, ReentrantLock JavaDoc lock, Condition JavaDoc condition) throws Exception JavaDoc {
486     Thread.currentThread().setName("GETTER-" + id);
487
488     int i = 0;
489     while (true) {
490       lock.lock();
491       lock.lock();
492       try {
493         while (queue.size() == 0) {
494           int choice = i % 4;
495           switch (choice) {
496             case 0:
497               condition.await();
498               break;
499             case 1:
500               condition.awaitUninterruptibly();
501               break;
502             case 2:
503               long millis = random.nextInt(10000);
504               condition.await(millis, TimeUnit.MILLISECONDS);
505               break;
506             case 3:
507               long nanos = random.nextInt(10000);
508               condition.awaitNanos(nanos);
509               break;
510           }
511           i++;
512         }
513         WorkItem wi = (WorkItem) queue.remove(0);
514         if (wi.isStop()) { return; }
515         System.err.println("GETTER- " + id + " removes " + wi);
516
517       } finally {
518         lock.unlock();
519         lock.unlock();
520       }
521     }
522   }
523
524   /**
525    * This test case makes sure that an unshared reentrant lock is functioning as normal.
526    */

527   private void basicUnsharedLockTesting(ReentrantLock JavaDoc unsharedLock) throws Exception JavaDoc {
528     clear();
529
530     int index = -1;
531     synchronized (root) {
532       index = root.getIndex();
533       if (index == 0) {
534         root.setIndex(1);
535       }
536     }
537
538     barrier.await();
539
540     if (index == 0) {
541       unsharedLock.lock();
542     }
543
544     barrier.await();
545
546     if (index == 0) {
547       Assert.assertTrue(unsharedLock.isLocked());
548     } else {
549       Assert.assertFalse(unsharedLock.isLocked());
550     }
551
552     barrier.await();
553
554     if (index != 0) {
555       boolean haveLock = unsharedLock.tryLock();
556       Assert.assertTrue(haveLock);
557     }
558
559     barrier.await();
560
561     if (index == 0) {
562       Assert.assertTrue(unsharedLock.isLocked());
563     } else {
564       Assert.assertTrue(unsharedLock.isLocked());
565     }
566
567     barrier.await();
568
569     if (index == 0) {
570       unsharedLock.unlock();
571     }
572
573     barrier.await();
574
575     if (index == 0) {
576       Assert.assertFalse(unsharedLock.isLocked());
577     } else {
578       Assert.assertTrue(unsharedLock.isLocked());
579     }
580
581     barrier.await();
582
583     if (index != 0) {
584       unsharedLock.unlock();
585     }
586
587     barrier.await();
588
589     if (index == 0) {
590       Assert.assertFalse(unsharedLock.isLocked());
591     } else {
592       Assert.assertFalse(unsharedLock.isLocked());
593     }
594
595     barrier.await();
596   }
597
598   /**
599    * This test case tests if tryLock() will throw an InterruptedException when the thread is interrupted.
600    */

601
602   private void threadInterruptedLockTesting(ReentrantLock JavaDoc lock) throws Exception JavaDoc {
603     clear();
604     int index = -1;
605     synchronized (root) {
606       index = root.getIndex();
607       if (index == 0) {
608         root.setIndex(1);
609       }
610     }
611     barrier.await();
612     if (index == 0) {
613       lock.lock();
614     }
615     barrier.await();
616     Thread JavaDoc thread = new Thread JavaDoc(new InterruptedRunnable(lock));
617     if (index == 0) {
618       thread.start();
619     }
620     barrier.await();
621     if (index == 0) {
622       thread.interrupt();
623       lock.unlock();
624     }
625     barrier.await();
626   }
627
628   /**
629    * This test case makes sure that data modifications within lock() and unlock() are reflected in the other client.
630    */

631   private void lockSyncLockTesting(ReentrantLock JavaDoc lock) throws Exception JavaDoc {
632     clear();
633
634     int index = -1;
635     synchronized (root) {
636       index = root.getIndex();
637       if (index == 0) {
638         root.setIndex(1);
639       }
640     }
641
642     barrier.await();
643
644     if (index == 0) {
645       lock.lock();
646       try {
647         root.setData(10);
648       } finally {
649         lock.unlock();
650       }
651     }
652
653     barrier.await();
654
655     Assert.assertEquals(10, root.getData());
656
657     barrier.await();
658   }
659
660   private void tryLockTesting(final ReentrantLock JavaDoc lock) throws Exception JavaDoc {
661     clear();
662
663     int index = -1;
664     synchronized (root) {
665       index = root.getIndex();
666       root.setIndex(index + 1);
667     }
668
669     barrier.await();
670
671     if (index == 1) {
672       final CyclicBarrier JavaDoc localBarrier = new CyclicBarrier JavaDoc(3);
673       final CyclicBarrier JavaDoc threadBarrier = new CyclicBarrier JavaDoc(2);
674
675       Thread JavaDoc t1 = new Thread JavaDoc(new Runnable JavaDoc() {
676         public void run() {
677           lock.lock();
678           try {
679             threadBarrier.await();
680             threadBarrier.await();
681           } catch (Exception JavaDoc e) {
682             throw new AssertionError JavaDoc(e);
683           } finally {
684             lock.unlock();
685           }
686           try {
687             localBarrier.await();
688           } catch (Exception JavaDoc e) {
689             throw new AssertionError JavaDoc(e);
690           }
691         }
692       });
693       Thread JavaDoc t2 = new Thread JavaDoc(new Runnable JavaDoc() {
694         public void run() {
695           try {
696             threadBarrier.await();
697             boolean isLocked = lock.tryLock();
698             threadBarrier.await();
699             Assert.assertFalse(isLocked);
700           } catch (Exception JavaDoc e) {
701             throw new AssertionError JavaDoc(e);
702           }
703           try {
704             localBarrier.await();
705           } catch (Exception JavaDoc e) {
706             throw new AssertionError JavaDoc(e);
707           }
708         }
709       });
710       t1.start();
711       t2.start();
712       localBarrier.await();
713     }
714
715     barrier.await();
716
717     if (index == 0) {
718       final CyclicBarrier JavaDoc localBarrier = new CyclicBarrier JavaDoc(3);
719       final CyclicBarrier JavaDoc threadBarrier = new CyclicBarrier JavaDoc(2);
720       final ReentrantLock JavaDoc nonSharedLock = new ReentrantLock JavaDoc();
721
722       Thread JavaDoc t1 = new Thread JavaDoc(new Runnable JavaDoc() {
723         public void run() {
724           nonSharedLock.lock();
725           try {
726             threadBarrier.await();
727             threadBarrier.await();
728           } catch (Exception JavaDoc e) {
729             throw new AssertionError JavaDoc(e);
730           } finally {
731             nonSharedLock.unlock();
732           }
733           try {
734             localBarrier.await();
735           } catch (Exception JavaDoc e) {
736             throw new AssertionError JavaDoc(e);
737           }
738         }
739       });
740
741       Thread JavaDoc t2 = new Thread JavaDoc(new Runnable JavaDoc() {
742         public void run() {
743           try {
744             threadBarrier.await();
745             boolean isLocked = nonSharedLock.tryLock();
746             threadBarrier.await();
747             Assert.assertFalse(isLocked);
748           } catch (Exception JavaDoc e) {
749             throw new AssertionError JavaDoc(e);
750           }
751           try {
752             localBarrier.await();
753           } catch (Exception JavaDoc e) {
754             throw new AssertionError JavaDoc(e);
755           }
756         }
757       });
758       t1.start();
759       t2.start();
760       localBarrier.await();
761     }
762
763     barrier.await();
764
765     if (index == 0) {
766       final CyclicBarrier JavaDoc localBarrier = new CyclicBarrier JavaDoc(2);
767       final ReentrantLock JavaDoc nonSharedLock = new ReentrantLock JavaDoc();
768
769       Thread JavaDoc t1 = new Thread JavaDoc(new Runnable JavaDoc() {
770         public void run() {
771           try {
772             boolean isLocked = nonSharedLock.tryLock();
773             Assert.assertTrue(isLocked);
774             nonSharedLock.unlock();
775           } catch (Exception JavaDoc e) {
776             throw new AssertionError JavaDoc(e);
777           }
778           try {
779             localBarrier.await();
780           } catch (Exception JavaDoc e) {
781             throw new AssertionError JavaDoc(e);
782           }
783         }
784       });
785       t1.start();
786       localBarrier.await();
787     }
788
789     barrier.await();
790
791   }
792
793   private void tryLockTimeoutTesting(final ReentrantLock JavaDoc lock) throws Exception JavaDoc {
794     clear();
795
796     int index = -1;
797     synchronized (root) {
798       index = root.getIndex();
799       root.setIndex(index + 1);
800     }
801
802     barrier.await();
803
804     if (index == 1) {
805       final CyclicBarrier JavaDoc localBarrier = new CyclicBarrier JavaDoc(3);
806       Thread JavaDoc t1 = new Thread JavaDoc(new Runnable JavaDoc() {
807         public void run() {
808           lock.lock();
809           try {
810             Thread.sleep(1000);
811           } catch (InterruptedException JavaDoc e) {
812             throw new AssertionError JavaDoc(e);
813           } finally {
814             lock.unlock();
815           }
816           try {
817             localBarrier.await();
818           } catch (Exception JavaDoc e) {
819             throw new AssertionError JavaDoc(e);
820           }
821         }
822       });
823       Thread JavaDoc t2 = new Thread JavaDoc(new Runnable JavaDoc() {
824         public void run() {
825           try {
826             boolean isLocked = lock.tryLock(4000, TimeUnit.MILLISECONDS);
827             Assert.assertTrue(isLocked);
828             lock.unlock();
829           } catch (InterruptedException JavaDoc e) {
830             throw new AssertionError JavaDoc(e);
831           }
832           try {
833             localBarrier.await();
834           } catch (Exception JavaDoc e) {
835             throw new AssertionError JavaDoc(e);
836           }
837         }
838       });
839       t1.start();
840       t2.start();
841       localBarrier.await();
842     }
843
844     barrier.await();
845
846     if (index == 0) {
847       final CyclicBarrier JavaDoc localBarrier = new CyclicBarrier JavaDoc(3);
848       final ReentrantLock JavaDoc nonSharedLock = new ReentrantLock JavaDoc();
849
850       Thread JavaDoc t1 = new Thread JavaDoc(new Runnable JavaDoc() {
851         public void run() {
852           nonSharedLock.lock();
853           try {
854             Thread.sleep(1000);
855           } catch (InterruptedException JavaDoc e) {
856             throw new AssertionError JavaDoc(e);
857           } finally {
858             nonSharedLock.unlock();
859           }
860           try {
861             localBarrier.await();
862           } catch (Exception JavaDoc e) {
863             throw new AssertionError JavaDoc(e);
864           }
865         }
866       });
867
868       Thread JavaDoc t2 = new Thread JavaDoc(new Runnable JavaDoc() {
869         public void run() {
870           try {
871             boolean isLocked = nonSharedLock.tryLock(4, TimeUnit.SECONDS);
872             Assert.assertTrue(isLocked);
873             nonSharedLock.unlock();
874           } catch (InterruptedException JavaDoc e) {
875             throw new AssertionError JavaDoc(e);
876           }
877           try {
878             localBarrier.await();
879           } catch (Exception JavaDoc e) {
880             throw new AssertionError JavaDoc(e);
881           }
882         }
883       });
884       t1.start();
885       t2.start();
886       localBarrier.await();
887     }
888
889     barrier.await();
890
891     if (index == 0) {
892       final CyclicBarrier JavaDoc localBarrier = new CyclicBarrier JavaDoc(3);
893       final ReentrantLock JavaDoc nonSharedLock = new ReentrantLock JavaDoc();
894
895       Thread JavaDoc t1 = new Thread JavaDoc(new Runnable JavaDoc() {
896         public void run() {
897           nonSharedLock.lock();
898           try {
899             Thread.sleep(1000);
900           } catch (InterruptedException JavaDoc e) {
901             throw new AssertionError JavaDoc(e);
902           } finally {
903             nonSharedLock.unlock();
904           }
905           try {
906             localBarrier.await();
907           } catch (Exception JavaDoc e) {
908             throw new AssertionError JavaDoc(e);
909           }
910         }
911       });
912
913       Thread JavaDoc t2 = new Thread JavaDoc(new Runnable JavaDoc() {
914         public void run() {
915           try {
916             boolean isLocked = nonSharedLock.tryLock(TimeUnit.MICROSECONDS.convert(4, TimeUnit.SECONDS),
917                                                      TimeUnit.MICROSECONDS);
918             Assert.assertTrue(isLocked);
919             nonSharedLock.unlock();
920           } catch (InterruptedException JavaDoc e) {
921             throw new AssertionError JavaDoc(e);
922           }
923           try {
924             localBarrier.await();
925           } catch (Exception JavaDoc e) {
926             throw new AssertionError JavaDoc(e);
927           }
928         }
929       });
930       t1.start();
931       t2.start();
932       localBarrier.await();
933     }
934
935     barrier.await();
936
937     if (index == 0) {
938       final CyclicBarrier JavaDoc localBarrier = new CyclicBarrier JavaDoc(3);
939       final CyclicBarrier JavaDoc threadBarrier = new CyclicBarrier JavaDoc(2);
940       final ReentrantLock JavaDoc nonSharedLock = new ReentrantLock JavaDoc();
941
942       Thread JavaDoc t1 = new Thread JavaDoc(new Runnable JavaDoc() {
943         public void run() {
944           nonSharedLock.lock();
945           try {
946             threadBarrier.await();
947             threadBarrier.await();
948           } catch (Exception JavaDoc e) {
949             throw new AssertionError JavaDoc(e);
950           } finally {
951             nonSharedLock.unlock();
952           }
953           try {
954             localBarrier.await();
955           } catch (Exception JavaDoc e) {
956             throw new AssertionError JavaDoc(e);
957           }
958         }
959       });
960
961       Thread JavaDoc t2 = new Thread JavaDoc(new Runnable JavaDoc() {
962         public void run() {
963           try {
964             threadBarrier.await();
965             boolean isLocked = nonSharedLock.tryLock(10, TimeUnit.MICROSECONDS);
966             threadBarrier.await();
967             Assert.assertFalse(isLocked);
968           } catch (Exception JavaDoc e) {
969             throw new AssertionError JavaDoc(e);
970           }
971           try {
972             localBarrier.await();
973           } catch (Exception JavaDoc e) {
974             throw new AssertionError JavaDoc(e);
975           }
976         }
977       });
978       t1.start();
979       t2.start();
980       localBarrier.await();
981     }
982
983     barrier.await();
984
985   }
986
987   /**
988    * This test case provides basic testing to the API of an reentrant lock when an reentrant lock is shared.
989    */

990   private void basicLockTesting(ReentrantLock JavaDoc lock) throws Exception JavaDoc {
991     clear();
992
993     int index = -1;
994     synchronized (root) {
995       index = root.getIndex();
996       if (index == 0) {
997         root.setIndex(1);
998       }
999     }
1000
1001    barrier.await();
1002
1003    if (index == 0) {
1004      lock.lock();
1005      boolean isLocked = lock.tryLock();
1006
1007      Assert.assertTrue(isLocked);
1008
1009      isLocked = lock.tryLock(300000L, TimeUnit.NANOSECONDS);
1010
1011      Assert.assertTrue(isLocked);
1012
1013      lock.unlock();
1014
1015      try {
1016        lock.hasQueuedThread(Thread.currentThread());
1017        throw new AssertionError JavaDoc("Should have thrown an TCNotSupportedMethodException.");
1018      } catch (TCNotSupportedMethodException e) {
1019        // Expected
1020
}
1021    }
1022    barrier.await();
1023
1024    if (index != 0) {
1025      boolean haveLocked = lock.tryLock();
1026      Assert.assertFalse(haveLocked);
1027
1028      haveLocked = lock.tryLock(300000L, TimeUnit.NANOSECONDS);
1029      Assert.assertFalse(haveLocked);
1030    }
1031
1032    barrier.await();
1033
1034    if (index == 0) {
1035      Assert.assertEquals(2, lock.getHoldCount());
1036    } else {
1037      Assert.assertEquals(0, lock.getHoldCount());
1038    }
1039
1040    Assert.assertEquals(0, lock.getQueueLength());
1041
1042    Assert.assertFalse(lock.hasQueuedThreads());
1043
1044    if (index == 0) {
1045      Assert.assertTrue(lock.isHeldByCurrentThread());
1046    } else {
1047      Assert.assertFalse(lock.isHeldByCurrentThread());
1048    }
1049    Assert.assertTrue(lock.isLocked());
1050
1051    barrier.await();
1052
1053    if (index == 0) {
1054      lock.unlock();
1055    }
1056
1057    barrier.await();
1058
1059    Assert.assertTrue(lock.isLocked());
1060
1061    barrier.await();
1062
1063    if (index == 0) {
1064      lock.unlock();
1065    }
1066
1067    barrier.await();
1068
1069    if (index == 0) {
1070      Assert.assertEquals(0, lock.getQueueLength());
1071      Assert.assertFalse(lock.isLocked());
1072    } else {
1073      Assert.assertTrue(lock.isLocked()); // due to greedy lock.
1074
}
1075
1076    barrier.await();
1077  }
1078
1079  public static void visitL1DSOConfig(ConfigVisitor visitor, DSOClientConfigHelper config) {
1080    String JavaDoc testClass = ReentrantLockTestApp.class.getName();
1081    TransparencyClassSpec spec = config.getOrCreateSpec(testClass);
1082
1083    config.addIncludePattern(testClass + "$*");
1084
1085    String JavaDoc methodExpression = "* " + testClass + "*.*(..)";
1086    config.addWriteAutolock(methodExpression);
1087
1088    spec.addRoot("root", "root");
1089    spec.addRoot("barrier", "barrier");
1090    spec.addRoot("barrier2", "barrier2");
1091    spec.addRoot("queue", "queue");
1092    spec.addRoot("testLockObject", "testLockObject");
1093  }
1094
1095  private static class TestRunnable1 implements Runnable JavaDoc {
1096    private ReentrantLock JavaDoc lock;
1097    private Condition JavaDoc conditionObject;
1098
1099    public TestRunnable1(ReentrantLock JavaDoc lock, Condition JavaDoc conditionObject) {
1100      this.lock = lock;
1101      this.conditionObject = conditionObject;
1102    }
1103
1104    public void run() {
1105      lock.lock();
1106      try {
1107        conditionObject.await();
1108      } catch (InterruptedException JavaDoc e) {
1109        throw new TCRuntimeException(e);
1110      } finally {
1111        lock.unlock();
1112      }
1113    }
1114  }
1115
1116  private class TestRunnable2 implements Runnable JavaDoc {
1117    private ReentrantLock JavaDoc lock;
1118
1119    public TestRunnable2(ReentrantLock JavaDoc lock) {
1120      this.lock = lock;
1121    }
1122
1123    public void run() {
1124      lock.lock();
1125      try {
1126        Thread.sleep(10000);
1127      } catch (InterruptedException JavaDoc e) {
1128        throw new TCRuntimeException(e);
1129      } finally {
1130        lock.unlock();
1131        try {
1132          barrier2.await();
1133        } catch (InterruptedException JavaDoc e) {
1134          throw new TCRuntimeException(e);
1135        } catch (BrokenBarrierException JavaDoc e) {
1136          throw new TCRuntimeException(e);
1137        }
1138      }
1139    }
1140  }
1141
1142  private class InterruptedRunnable implements Runnable JavaDoc {
1143    private ReentrantLock JavaDoc lock;
1144
1145    public InterruptedRunnable(ReentrantLock JavaDoc lock) {
1146      this.lock = lock;
1147    }
1148
1149    public void run() {
1150      try {
1151        try {
1152          lock.lock();
1153        } catch (TCRuntimeException e) {
1154          Assert.assertFalse(isCausedByInterruptedException(e));
1155        }
1156      } finally {
1157        lock.unlock();
1158      }
1159
1160    }
1161  }
1162
1163  private boolean isCausedByInterruptedException(TCRuntimeException e) {
1164    if (e.getCause() instanceof InterruptedException JavaDoc) {
1165      return true;
1166    } else {
1167      return false;
1168    }
1169  }
1170
1171  private class TestTryLockFailRunnable implements Runnable JavaDoc {
1172    private String JavaDoc lockId;
1173    private CyclicBarrier JavaDoc barrier;
1174
1175    public TestTryLockFailRunnable(String JavaDoc lockId, CyclicBarrier JavaDoc barrier) {
1176      this.lockId = lockId;
1177      this.barrier = barrier;
1178    }
1179
1180    public void run() {
1181      try {
1182        boolean locked = ManagerUtil.tryBeginLock(lockId, LockLevel.WRITE);
1183
1184        Assert.assertFalse(locked);
1185        this.barrier.await();
1186      } catch (Exception JavaDoc e) {
1187        throw new TCRuntimeException(e);
1188      }
1189    }
1190  }
1191
1192  /*
1193   * private static class TestRunnable3 implements Runnable { private ReentrantLock lock; private Object sharedObject;
1194   * public TestRunnable3(ReentrantLock lock, Object obj) { this.lock = lock; this.sharedObject = obj; } public void
1195   * run() { synchronized(sharedObject) { try { lock.lock(); sharedObject.wait(); } catch (InterruptedException e) {
1196   * lock.unlock(); } finally { lock.unlock(); } } } }
1197   */

1198
1199  private static class DataRoot {
1200    private ReentrantLock JavaDoc unfairLock = new ReentrantLock JavaDoc();
1201
1202    // When an reentrant lock is shared,
1203
// the fairness is current not supported.
1204
private ReentrantLock JavaDoc fairLock = new ReentrantLock JavaDoc(true);
1205    private Condition JavaDoc unfairCondition = unfairLock.newCondition();
1206    private Condition JavaDoc fairCondition = fairLock.newCondition();
1207    private ReentrantLock JavaDoc lazyLock;
1208    private int data;
1209    private int index;
1210
1211    public DataRoot() {
1212      this.index = 0;
1213    }
1214
1215    public int getIndex() {
1216      return index;
1217    }
1218
1219    public void setIndex(int index) {
1220      this.index = index;
1221    }
1222
1223    public ReentrantLock JavaDoc getFairLock() {
1224      return fairLock;
1225    }
1226
1227    public void setFairLock(ReentrantLock JavaDoc fairLock) {
1228      this.fairLock = fairLock;
1229    }
1230
1231    public ReentrantLock JavaDoc getUnfairLock() {
1232      return unfairLock;
1233    }
1234
1235    public void setUnfairLock(ReentrantLock JavaDoc unfairLock) {
1236      this.unfairLock = unfairLock;
1237    }
1238
1239    public int getData() {
1240      return data;
1241    }
1242
1243    public void setData(int data) {
1244      this.data = data;
1245    }
1246
1247    public ReentrantLock JavaDoc getLazyLock() {
1248      return lazyLock;
1249    }
1250
1251    public void setLazyLock(ReentrantLock JavaDoc lazyLock) {
1252      this.lazyLock = lazyLock;
1253    }
1254
1255    public Condition JavaDoc getUnfairCondition() {
1256      return unfairCondition;
1257    }
1258
1259    public void setUnfairCondition(Condition JavaDoc unfairCondition) {
1260      this.unfairCondition = unfairCondition;
1261    }
1262
1263    public Condition JavaDoc getFairCondition() {
1264      return fairCondition;
1265    }
1266
1267    public void setFairCondition(Condition JavaDoc fairCondition) {
1268      this.fairCondition = fairCondition;
1269    }
1270
1271    public void clear() {
1272      this.index = 0;
1273      this.data = 0;
1274    }
1275  }
1276
1277  private static class WorkItem {
1278    static final WorkItem STOP = new WorkItem("STOP");
1279
1280    private final String JavaDoc name;
1281
1282    WorkItem(String JavaDoc name) {
1283      this.name = name;
1284    }
1285
1286    boolean isStop() {
1287      return STOP.name.equals(name);
1288    }
1289
1290    public String JavaDoc toString() {
1291      return this.name;
1292    }
1293  }
1294}
1295
Popular Tags