Reentrant access examples rewritten to make a bit more sence
authorJaroslav Tulach <jtulach@netbeans.org>
Sat, 14 Jun 2008 09:54:37 +0200
changeset 11264308321f7bd
parent 111 3905a2e66b9b
child 113 f2b6057a3376
Reentrant access examples rewritten to make a bit more sence
samples/reentrant/src/org/apidesign/reentrant/CriticalSectionReentrant.java
samples/reentrant/src/org/apidesign/reentrant/CriticalSectionReentrantForLoop.java
samples/reentrant/src/org/apidesign/reentrant/CriticalSectionSynchronizedWithAssert.java
samples/reentrant/src/org/apidesign/reentrant/CriticalSectionSynchronizedWithNonReentrantLock.java
samples/reentrant/test/org/apidesign/reentrant/CriticalSectionBase.java
samples/reentrant/test/org/apidesign/reentrant/CriticalSectionReentrantForLoopTest.java
     1.1 --- a/samples/reentrant/src/org/apidesign/reentrant/CriticalSectionReentrant.java	Sat Jun 14 09:54:36 2008 +0200
     1.2 +++ b/samples/reentrant/src/org/apidesign/reentrant/CriticalSectionReentrant.java	Sat Jun 14 09:54:37 2008 +0200
     1.3 @@ -13,16 +13,20 @@
     1.4  
     1.5      public int sumBigger(Collection<T> args) {
     1.6          T pilotCopy = this.pilot;
     1.7 +        int own = doCriticalSection(args, pilotCopy);
     1.8 +        // now merge with global state
     1.9 +        cnt.addAndGet(own);
    1.10 +        return own;
    1.11 +    }
    1.12 +    
    1.13 +    private int doCriticalSection(Collection<T> args, T pilotCopy) {
    1.14          int own = 0;
    1.15          for (T cmp : args) {
    1.16              if (pilotCopy.compareTo(cmp) < 0) {
    1.17                  own++;
    1.18              }
    1.19          }
    1.20 -        cnt.addAndGet(own);
    1.21          return own;
    1.22 -        
    1.23 -        
    1.24      }
    1.25  
    1.26      public int getCount() {
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/samples/reentrant/src/org/apidesign/reentrant/CriticalSectionReentrantForLoop.java	Sat Jun 14 09:54:37 2008 +0200
     2.3 @@ -0,0 +1,42 @@
     2.4 +package org.apidesign.reentrant;
     2.5 +
     2.6 +import java.util.Collection;
     2.7 +import java.util.concurrent.atomic.AtomicInteger;
     2.8 +
     2.9 +public class CriticalSectionReentrantForLoop<T extends Comparable<T>> implements CriticalSection<T> {
    2.10 +    private volatile T pilot;
    2.11 +    private AtomicInteger cnt = new AtomicInteger();
    2.12 +    
    2.13 +    public void assignPilot(T pilot) {
    2.14 +        this.pilot = pilot;
    2.15 +    }
    2.16 +
    2.17 +    // BEGIN: reentrant.merge.for
    2.18 +    public int sumBigger(Collection<T> args) {
    2.19 +        T pilotCopy = this.pilot;
    2.20 +        for (;;) {
    2.21 +            int previous = cnt.get();
    2.22 +            int own = doCriticalSection(args, pilotCopy);
    2.23 +            // if there was no parallel or reentrant change, 
    2.24 +            // apply and return. Otherwise try once more.
    2.25 +            if (cnt.compareAndSet(previous, own + previous)) {
    2.26 +                return own;
    2.27 +            }
    2.28 +        }
    2.29 +    }
    2.30 +    // END: reentrant.merge.for
    2.31 +    
    2.32 +    private int doCriticalSection(Collection<T> args, T pilotCopy) {
    2.33 +        int own = 0;
    2.34 +        for (T cmp : args) {
    2.35 +            if (pilotCopy.compareTo(cmp) < 0) {
    2.36 +                own++;
    2.37 +            }
    2.38 +        }
    2.39 +        return own;
    2.40 +    }
    2.41 +
    2.42 +    public int getCount() {
    2.43 +        return cnt.get();
    2.44 +    }
    2.45 +}
     3.1 --- a/samples/reentrant/src/org/apidesign/reentrant/CriticalSectionSynchronizedWithAssert.java	Sat Jun 14 09:54:36 2008 +0200
     3.2 +++ b/samples/reentrant/src/org/apidesign/reentrant/CriticalSectionSynchronizedWithAssert.java	Sat Jun 14 09:54:37 2008 +0200
     3.3 @@ -5,27 +5,34 @@
     3.4  public class CriticalSectionSynchronizedWithAssert<T extends Comparable<T>> implements CriticalSection<T> {
     3.5      private T pilot;
     3.6      private int cnt;
     3.7 -    private boolean working;
     3.8      
     3.9      public synchronized void assignPilot(T pilot) {
    3.10          assert !working : "Shall not be working yet in order to be consistent";
    3.11          this.pilot = pilot;
    3.12      }
    3.13  
    3.14 +    // BEGIN: reentrant.assert
    3.15 +    private boolean working;
    3.16      public int sumBigger(Collection<T> args) {
    3.17          assert !working : "Shall not be working yet in order to be consistent";
    3.18          working = true;
    3.19          try {
    3.20 -            for (T cmp : args) {
    3.21 -                if (pilot.compareTo(cmp) < 0) {
    3.22 -                    cnt++;
    3.23 -                }
    3.24 -            }
    3.25 -            return cnt;
    3.26 +            return doCriticalSection(args);
    3.27          } finally {
    3.28              working = false;
    3.29          }
    3.30      }
    3.31 +    // END: reentrant.assert
    3.32 +    
    3.33 +    
    3.34 +    private int doCriticalSection(Collection<T> args) {
    3.35 +        for (T cmp : args) {
    3.36 +            if (pilot.compareTo(cmp) < 0) {
    3.37 +                cnt++;
    3.38 +            }
    3.39 +        }
    3.40 +        return cnt;
    3.41 +    }
    3.42      
    3.43      public int getCount() {
    3.44          assert !working : "Shall not be working yet in order to be consistent";
     4.1 --- a/samples/reentrant/src/org/apidesign/reentrant/CriticalSectionSynchronizedWithNonReentrantLock.java	Sat Jun 14 09:54:36 2008 +0200
     4.2 +++ b/samples/reentrant/src/org/apidesign/reentrant/CriticalSectionSynchronizedWithNonReentrantLock.java	Sat Jun 14 09:54:37 2008 +0200
     4.3 @@ -7,7 +7,6 @@
     4.4  public class CriticalSectionSynchronizedWithNonReentrantLock<T extends Comparable<T>> implements CriticalSection<T> {
     4.5      private T pilot;
     4.6      private int cnt;
     4.7 -    private Lock lock = new NonReentrantLock();
     4.8      
     4.9      public void assignPilot(T pilot) {
    4.10          lock.lock();
    4.11 @@ -18,19 +17,26 @@
    4.12          }
    4.13      }
    4.14  
    4.15 +    // BEGIN: reentrant.nonreentrant.lock
    4.16 +    private Lock lock = new NonReentrantLock();
    4.17      public int sumBigger(Collection<T> args) {
    4.18          lock.lock();
    4.19          try {
    4.20 -            for (T cmp : args) {
    4.21 -                if (pilot.compareTo(cmp) < 0) {
    4.22 -                    cnt++;
    4.23 -                }
    4.24 -            }
    4.25 -            return cnt;
    4.26 +            return doCriticalSection(args);
    4.27          } finally {
    4.28              lock.unlock();
    4.29          }
    4.30      }
    4.31 +    // END: reentrant.nonreentrant.lock
    4.32 +    
    4.33 +    private int doCriticalSection(Collection<T> args) {
    4.34 +        for (T cmp : args) {
    4.35 +            if (pilot.compareTo(cmp) < 0) {
    4.36 +                cnt++;
    4.37 +            }
    4.38 +        }
    4.39 +        return cnt;
    4.40 +    }
    4.41      
    4.42      public int getCount() {
    4.43          lock.lock();
     5.1 --- a/samples/reentrant/test/org/apidesign/reentrant/CriticalSectionBase.java	Sat Jun 14 09:54:36 2008 +0200
     5.2 +++ b/samples/reentrant/test/org/apidesign/reentrant/CriticalSectionBase.java	Sat Jun 14 09:54:37 2008 +0200
     5.3 @@ -8,12 +8,17 @@
     5.4  
     5.5  public abstract class CriticalSectionBase {
     5.6      protected abstract CriticalSection<Integer> create();
     5.7 +    protected boolean reentrantJustOnce() {
     5.8 +        return false;
     5.9 +    }
    5.10  
    5.11 +    // BEGIN: reentrant.ok.call
    5.12      @Test
    5.13      public void testCriticalSectionWith15() {
    5.14          final CriticalSection<Integer> cs = create();
    5.15          testFor15(cs);
    5.16      }
    5.17 +    // END: reentrant.ok.call
    5.18      
    5.19      final void testFor15(CriticalSection<Integer> cs) {
    5.20          cs.assignPilot(15);
    5.21 @@ -41,9 +46,13 @@
    5.22          cs.assignPilot(10);
    5.23          
    5.24          class ChangePilotTo15 implements Runnable {
    5.25 +            // BEGIN: reentrant.forbidden.call
    5.26 +            // if this runnable is called from inside the critical section,
    5.27 +            // and the locks are non-reentrant then it throws an exception
    5.28              public void run() {
    5.29                  testFor15(cs);
    5.30              }
    5.31 +            // END: reentrant.forbidden.call
    5.32          }
    5.33          
    5.34          List<Integer> ints = new MyCollection(new ChangePilotTo15(), 3);
    5.35 @@ -64,7 +73,7 @@
    5.36      }
    5.37  
    5.38      class MyCollection extends ArrayList<Integer> {
    5.39 -        private final Runnable callback;
    5.40 +        private Runnable callback;
    5.41          private final int callbackBeforeIndex;
    5.42  
    5.43          public MyCollection(Runnable callback, int callbackAtIndex) {
    5.44 @@ -84,7 +93,12 @@
    5.45  
    5.46                  public Integer next() {
    5.47                      if (index++ == callbackBeforeIndex) {
    5.48 -                        callback.run();
    5.49 +                        if (callback != null) {
    5.50 +                            callback.run();
    5.51 +                        }
    5.52 +                        if (reentrantJustOnce()) {
    5.53 +                            callback = null;
    5.54 +                        }
    5.55                      }
    5.56                      
    5.57                      return delegate.next();
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/samples/reentrant/test/org/apidesign/reentrant/CriticalSectionReentrantForLoopTest.java	Sat Jun 14 09:54:37 2008 +0200
     6.3 @@ -0,0 +1,13 @@
     6.4 +package org.apidesign.reentrant;
     6.5 +
     6.6 +public class CriticalSectionReentrantForLoopTest extends CriticalSectionBase {
     6.7 +    @Override
     6.8 +    protected CriticalSection<Integer> create() {
     6.9 +        return new CriticalSectionReentrantForLoop<Integer>();
    6.10 +    }
    6.11 +
    6.12 +    @Override
    6.13 +    protected boolean reentrantJustOnce() {
    6.14 +        return true;
    6.15 +    }
    6.16 +}
    6.17 \ No newline at end of file