From ExtremeProgrammingChallengeFourteenTheBug. ---- import java.util.*; public class BoundedBuffer { synchronized void put(Object x) throws InterruptedException { /***/ TestBB.doSleep(); while ( occupied == buffer.length ) wait(); notify(); /***/ TestBB.doSleep(); ++occupied; putAt %= buffer.length; buffer[putAt++] = x; } synchronized Object take() throws InterruptedException { while ( occupied == 0 ) wait(); notify(); /***/ TestBB.doSleep(); --occupied; takeAt %= buffer.length; return buffer[takeAt++]; } private Object[] buffer = new Object[1]; private int putAt, takeAt, occupied; } class TestBB extends Thread { private static int[] c1sleeps = {0}; private static int[] c2sleeps = {0}; private static int[] p1sleeps = {0,0,250}; private static int[] p2sleeps = {0,500}; private static BoundedBuffer theBB = new BoundedBuffer(); private static Hashtable threads = new Hashtable(); public static void main(String[] args) throws Throwable { TestBB c1 = new TestBB(c1sleeps) { public void run() { try { System.out.println("C1 takes:"+theBB.take()); } catch (InterruptedException ie) {} } }; TestBB c2 = new TestBB(c2sleeps) { public void run() { try { System.out.println("C2 takes:"+theBB.take()); } catch (InterruptedException ie) {} } }; TestBB p1 = new TestBB(p1sleeps) { public void run() { try { System.out.println("P1 puts 'A'"); theBB.put("A"); } catch (InterruptedException ie) {} } }; TestBB p2 = new TestBB(p2sleeps) { public void run() { try { System.out.println("P2 puts 'B'"); theBB.put("B"); } catch (InterruptedException ie) {} } }; c1.start(); c2.start(); p1.start(); p2.start(); Thread.sleep(5000); if (p1.isAlive() || p2.isAlive()) { System.out.println("Liveness problem detected."); } } public TestBB(int[] sleeps) { threads.put(Thread.currentThread(),sleeps); } public static void doSleep() { int[] sleepsForThread = (int[])threads.get(Thread.currentThread()); if (sleepsForThread != null) { int current = sleepsForThread[0] % sleepsForThread.length; sleepsForThread[0]++; try { Thread.sleep(sleepsForThread[current]); } catch(InterruptedException ie) {} } } }