Concurrency Unit Test Final Version

From ExtremeProgrammingChallengeFourteenTheBug


import java.util.*;

public class BoundedBuffer {

    synchronized
void put(Object x) throws InterruptedException {
    while ( occupied == buffer.length ) {
wait();
    }
    /***/ TestBB.doSleep();
    notify();
    /***/ TestBB.doSleep();
    ++occupied;
    putAt %= buffer.length;
    buffer[putAt++] = x;
}

synchronized Object take() throws InterruptedException { while ( occupied == 0 ) { wait(); } /***/ TestBB.doSleep(); notify(); --occupied; takeAt %= buffer.length; return buffer[takeAt++]; }

private Object[] buffer = new Object[1]; private int putAt, takeAt, occupied;

}

class TestBB extends Thread {

private static final int slow = 10;

private static int[]c1sleeps = {0,slow}; private static int[]c2sleeps = {0,0}; private static int[]p1sleeps = {0,slow*2,slow*2}; private static int[]p2sleeps = {0,0,0};

private static BoundedBuffertheBB = new BoundedBuffer(); private static Hashtablethreads = new Hashtable();

public static void main(String[] args) throws Throwable { int pass = 0; int fail = 0; for (int i=0; i< 50; i++) { if (doTest()) { System.out.println("Fail."); fail++; } else { System.out.println("Pass."); pass++; } } System.out.println("Slow is "+slow+", false pass:"+pass+", fail:"+fail); }

public static boolean doTest() throws Throwable { theBB = new BoundedBuffer(); c1sleeps[0] = 0; c2sleeps[0] = 0; p1sleeps[0] = 0; p2sleeps[0] = 0; TestBB c1 = new TestBB("c1",c1sleeps) { public void run() { try { theBB.take(); } catch (InterruptedException ie) {} } }; TestBB c2 = new TestBB("c2",c2sleeps) { public void run() { try { theBB.take(); } catch (InterruptedException ie) {} } }; TestBB p1 = new TestBB("p1",p1sleeps) { public void run() { try { theBB.put("A"); } catch (InterruptedException ie) {} } }; TestBB p2 = new TestBB("p2",p2sleeps) { public void run() { try { theBB.put("B"); } catch (InterruptedException ie) {} } }; c1.start(); Thread.sleep(slow); c2.start(); Thread.sleep(slow); p1.start(); Thread.sleep(slow); p2.start(); Thread.sleep(300+(slow*10)); if (p2.isAlive()) { System.out.println("Liveness problem detected."); return true; } else return false; }

public TestBB(String name,int[] sleeps) { super(name); threads.put(this,sleeps); }

public static void doSleep() { int[] sleepsForThread = (int[])threads.get(Thread.currentThread()); if (sleepsForThread != null) { int current = 1+(sleepsForThread[0] % (sleepsForThread.length-1)); sleepsForThread[0]++; try { Thread.sleep(sleepsForThread[current]); } catch(InterruptedException ie) {} } }
}


EditText of this page (last edited November 2, 2000) or FindPage with title or text search