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 BoundedBuffer theBB = new BoundedBuffer();
private static Hashtable threads = 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) {},
},
},
},