# HG changeset patch # User Jaroslav Tulach # Date 1213430077 -7200 # Node ID 64308321f7bd9538758bb5957997170ed5f1302b # Parent 3905a2e66b9b68f6a54aa33538275118934a51ea Reentrant access examples rewritten to make a bit more sence diff -r 3905a2e66b9b -r 64308321f7bd samples/reentrant/src/org/apidesign/reentrant/CriticalSectionReentrant.java --- a/samples/reentrant/src/org/apidesign/reentrant/CriticalSectionReentrant.java Sat Jun 14 09:54:36 2008 +0200 +++ b/samples/reentrant/src/org/apidesign/reentrant/CriticalSectionReentrant.java Sat Jun 14 09:54:37 2008 +0200 @@ -13,16 +13,20 @@ public int sumBigger(Collection args) { T pilotCopy = this.pilot; + int own = doCriticalSection(args, pilotCopy); + // now merge with global state + cnt.addAndGet(own); + return own; + } + + private int doCriticalSection(Collection args, T pilotCopy) { int own = 0; for (T cmp : args) { if (pilotCopy.compareTo(cmp) < 0) { own++; } } - cnt.addAndGet(own); return own; - - } public int getCount() { diff -r 3905a2e66b9b -r 64308321f7bd samples/reentrant/src/org/apidesign/reentrant/CriticalSectionReentrantForLoop.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/samples/reentrant/src/org/apidesign/reentrant/CriticalSectionReentrantForLoop.java Sat Jun 14 09:54:37 2008 +0200 @@ -0,0 +1,42 @@ +package org.apidesign.reentrant; + +import java.util.Collection; +import java.util.concurrent.atomic.AtomicInteger; + +public class CriticalSectionReentrantForLoop> implements CriticalSection { + private volatile T pilot; + private AtomicInteger cnt = new AtomicInteger(); + + public void assignPilot(T pilot) { + this.pilot = pilot; + } + + // BEGIN: reentrant.merge.for + public int sumBigger(Collection args) { + T pilotCopy = this.pilot; + for (;;) { + int previous = cnt.get(); + int own = doCriticalSection(args, pilotCopy); + // if there was no parallel or reentrant change, + // apply and return. Otherwise try once more. + if (cnt.compareAndSet(previous, own + previous)) { + return own; + } + } + } + // END: reentrant.merge.for + + private int doCriticalSection(Collection args, T pilotCopy) { + int own = 0; + for (T cmp : args) { + if (pilotCopy.compareTo(cmp) < 0) { + own++; + } + } + return own; + } + + public int getCount() { + return cnt.get(); + } +} diff -r 3905a2e66b9b -r 64308321f7bd samples/reentrant/src/org/apidesign/reentrant/CriticalSectionSynchronizedWithAssert.java --- a/samples/reentrant/src/org/apidesign/reentrant/CriticalSectionSynchronizedWithAssert.java Sat Jun 14 09:54:36 2008 +0200 +++ b/samples/reentrant/src/org/apidesign/reentrant/CriticalSectionSynchronizedWithAssert.java Sat Jun 14 09:54:37 2008 +0200 @@ -5,27 +5,34 @@ public class CriticalSectionSynchronizedWithAssert> implements CriticalSection { private T pilot; private int cnt; - private boolean working; public synchronized void assignPilot(T pilot) { assert !working : "Shall not be working yet in order to be consistent"; this.pilot = pilot; } + // BEGIN: reentrant.assert + private boolean working; public int sumBigger(Collection args) { assert !working : "Shall not be working yet in order to be consistent"; working = true; try { - for (T cmp : args) { - if (pilot.compareTo(cmp) < 0) { - cnt++; - } - } - return cnt; + return doCriticalSection(args); } finally { working = false; } } + // END: reentrant.assert + + + private int doCriticalSection(Collection args) { + for (T cmp : args) { + if (pilot.compareTo(cmp) < 0) { + cnt++; + } + } + return cnt; + } public int getCount() { assert !working : "Shall not be working yet in order to be consistent"; diff -r 3905a2e66b9b -r 64308321f7bd samples/reentrant/src/org/apidesign/reentrant/CriticalSectionSynchronizedWithNonReentrantLock.java --- a/samples/reentrant/src/org/apidesign/reentrant/CriticalSectionSynchronizedWithNonReentrantLock.java Sat Jun 14 09:54:36 2008 +0200 +++ b/samples/reentrant/src/org/apidesign/reentrant/CriticalSectionSynchronizedWithNonReentrantLock.java Sat Jun 14 09:54:37 2008 +0200 @@ -7,7 +7,6 @@ public class CriticalSectionSynchronizedWithNonReentrantLock> implements CriticalSection { private T pilot; private int cnt; - private Lock lock = new NonReentrantLock(); public void assignPilot(T pilot) { lock.lock(); @@ -18,19 +17,26 @@ } } + // BEGIN: reentrant.nonreentrant.lock + private Lock lock = new NonReentrantLock(); public int sumBigger(Collection args) { lock.lock(); try { - for (T cmp : args) { - if (pilot.compareTo(cmp) < 0) { - cnt++; - } - } - return cnt; + return doCriticalSection(args); } finally { lock.unlock(); } } + // END: reentrant.nonreentrant.lock + + private int doCriticalSection(Collection args) { + for (T cmp : args) { + if (pilot.compareTo(cmp) < 0) { + cnt++; + } + } + return cnt; + } public int getCount() { lock.lock(); diff -r 3905a2e66b9b -r 64308321f7bd samples/reentrant/test/org/apidesign/reentrant/CriticalSectionBase.java --- a/samples/reentrant/test/org/apidesign/reentrant/CriticalSectionBase.java Sat Jun 14 09:54:36 2008 +0200 +++ b/samples/reentrant/test/org/apidesign/reentrant/CriticalSectionBase.java Sat Jun 14 09:54:37 2008 +0200 @@ -8,12 +8,17 @@ public abstract class CriticalSectionBase { protected abstract CriticalSection create(); + protected boolean reentrantJustOnce() { + return false; + } + // BEGIN: reentrant.ok.call @Test public void testCriticalSectionWith15() { final CriticalSection cs = create(); testFor15(cs); } + // END: reentrant.ok.call final void testFor15(CriticalSection cs) { cs.assignPilot(15); @@ -41,9 +46,13 @@ cs.assignPilot(10); class ChangePilotTo15 implements Runnable { + // BEGIN: reentrant.forbidden.call + // if this runnable is called from inside the critical section, + // and the locks are non-reentrant then it throws an exception public void run() { testFor15(cs); } + // END: reentrant.forbidden.call } List ints = new MyCollection(new ChangePilotTo15(), 3); @@ -64,7 +73,7 @@ } class MyCollection extends ArrayList { - private final Runnable callback; + private Runnable callback; private final int callbackBeforeIndex; public MyCollection(Runnable callback, int callbackAtIndex) { @@ -84,7 +93,12 @@ public Integer next() { if (index++ == callbackBeforeIndex) { - callback.run(); + if (callback != null) { + callback.run(); + } + if (reentrantJustOnce()) { + callback = null; + } } return delegate.next(); diff -r 3905a2e66b9b -r 64308321f7bd samples/reentrant/test/org/apidesign/reentrant/CriticalSectionReentrantForLoopTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/samples/reentrant/test/org/apidesign/reentrant/CriticalSectionReentrantForLoopTest.java Sat Jun 14 09:54:37 2008 +0200 @@ -0,0 +1,13 @@ +package org.apidesign.reentrant; + +public class CriticalSectionReentrantForLoopTest extends CriticalSectionBase { + @Override + protected CriticalSection create() { + return new CriticalSectionReentrantForLoop(); + } + + @Override + protected boolean reentrantJustOnce() { + return true; + } +} \ No newline at end of file