samples/reentrant/test/org/apidesign/reentrant/CriticalSectionBase.java
author Jaroslav Tulach <jtulach@netbeans.org>
Sat, 14 Jun 2008 09:54:37 +0200
changeset 112 64308321f7bd
parent 111 3905a2e66b9b
child 263 7e8e995065c5
permissions -rw-r--r--
Reentrant access examples rewritten to make a bit more sence
     1 package org.apidesign.reentrant;
     2 
     3 import java.util.ArrayList;
     4 import java.util.Iterator;
     5 import java.util.List;
     6 import org.junit.Test;
     7 import static org.junit.Assert.*;
     8 
     9 public abstract class CriticalSectionBase {
    10     protected abstract CriticalSection<Integer> create();
    11     protected boolean reentrantJustOnce() {
    12         return false;
    13     }
    14 
    15     // BEGIN: reentrant.ok.call
    16     @Test
    17     public void testCriticalSectionWith15() {
    18         final CriticalSection<Integer> cs = create();
    19         testFor15(cs);
    20     }
    21     // END: reentrant.ok.call
    22     
    23     final void testFor15(CriticalSection<Integer> cs) {
    24         cs.assignPilot(15);
    25 
    26         List<Integer> ints = new ArrayList<Integer>();
    27         ints.add(8);
    28         ints.add(11);
    29         ints.add(10);
    30         ints.add(5);
    31         ints.add(12);
    32         ints.add(18);
    33         ints.add(13);
    34         ints.add(7);
    35 
    36         int cnt = cs.sumBigger(ints);
    37 
    38         assertEquals("18 is bigger than 15", 1, cnt);
    39         
    40     }
    41     
    42     @Test 
    43     public void teaseCriticalSectionWithReentrantCalls() {
    44         final CriticalSection<Integer> cs = create();
    45         
    46         cs.assignPilot(10);
    47         
    48         class ChangePilotTo15 implements Runnable {
    49             // BEGIN: reentrant.forbidden.call
    50             // if this runnable is called from inside the critical section,
    51             // and the locks are non-reentrant then it throws an exception
    52             public void run() {
    53                 testFor15(cs);
    54             }
    55             // END: reentrant.forbidden.call
    56         }
    57         
    58         List<Integer> ints = new MyCollection(new ChangePilotTo15(), 3);
    59         ints.add(8);
    60         ints.add(11);
    61         ints.add(10);
    62         ints.add(5);
    63         ints.add(12);
    64         ints.add(18);
    65         ints.add(13);
    66         ints.add(7);
    67         
    68         int cnt = cs.sumBigger(ints);
    69         
    70         assertEquals("11, 12, 18, 13 are bigger than 10", 4, cnt);
    71         
    72         assertEquals("Global count is sum of ints(e.g. 4) plus result of testFor15(e.g. 1)", 5, cs.getCount());
    73     }
    74 
    75     class MyCollection extends ArrayList<Integer> {
    76         private Runnable callback;
    77         private final int callbackBeforeIndex;
    78 
    79         public MyCollection(Runnable callback, int callbackAtIndex) {
    80             this.callback = callback;
    81             this.callbackBeforeIndex = callbackAtIndex;
    82         }
    83 
    84         @Override
    85         public Iterator<Integer> iterator() {
    86             final Iterator<Integer> delegate = super.iterator();
    87             class It implements Iterator<Integer> {
    88                 private int index;
    89                 
    90                 public boolean hasNext() {
    91                     return delegate.hasNext();
    92                 }
    93 
    94                 public Integer next() {
    95                     if (index++ == callbackBeforeIndex) {
    96                         if (callback != null) {
    97                             callback.run();
    98                         }
    99                         if (reentrantJustOnce()) {
   100                             callback = null;
   101                         }
   102                     }
   103                     
   104                     return delegate.next();
   105                 }
   106 
   107                 public void remove() {
   108                     delegate.remove();
   109                 }
   110             } // end of It
   111             
   112             return new It();
   113         }
   114     }
   115 }