This is part of JavaUnitTestChallengeSolved ?DonWells
Now we can reverse and try to overwhelm a single put with 10 takes. We need to change the PutThread so that we can tell it to put 50 times instead of the usual 5. In this case I am going to specify how many sequences of abcde we want to output. I am just going to add a ConstructorMethod? for it. Now we can create out test.
public class OneAndTen extends Test { public BoundedBuffer buffer; public PutThread putThread; public TakeThread takeThreads []; public void setUp(){ buffer = new BoundedBuffer(); takeThreads = new TakeThread [10]; putThread = new PutThread(buffer, 10); for (int each = 0; each < 10; each++) { takeThreads[each] = new TakeThread(buffer);};} public void tearDown(){ TakeThread.dumpOutput();} public void runTest (){ TakeThread.resetOutput(); putThread.start(); for (int each = 0; each < 10; each++) { takeThreads[each].start();}; waitForPutToFinish(); sleepHalfSecond(); should(TakeThread.outputLength() == 50, "output was too short"); should(TakeThread.doesOuputHaveTenOf("a"), "should get ten a"); should(TakeThread.doesOuputHaveTenOf("b"), "should get ten b"); should(TakeThread.doesOuputHaveTenOf("c"), "should get ten c"); should(TakeThread.doesOuputHaveTenOf("d"), "should get ten d"); should(TakeThread.doesOuputHaveTenOf("e"), "should get ten e");} public void waitForPutToFinish(){ try { putThread.join(4000);} catch (InterruptedException exception) {};} }This is the third time now I have created a test that looks a lot like the twenty threads test. I could create a superclass and refactor out the similarities, but first I am going to make it work, then make it right, (and then make it fast).
Let's try this now.
This one doesn't run. The output was incomplete. I add a dump of the output buffer to see what is going on and I realize that the problem is that the PutThread is going to sleep when the buffer is filled. The take threads, which started first, are probably sleeping because they found an empty buffer. Now when the put thread runs it wakes up 4 take threads. Those 4 take threads empty the buffer and while doing so wake up other take threads, but not the put thread which is what is supposed to happen. Clearly this is a problem caused by the fact that take threads can wake up other take threads and are not specifically limited to waking up the put threads as they should be. This is not the exact scenario that TomCargill proposed, but it is caused by the same underlying bug.