I do have the actual classes to be used in the testing though, and here they are:
Of course our class will extend Thread, because we want it to be multithreaded. The constructor just assigns values to the global variables that we'll be using to test, and then we have the thread running method.
In this method, we have a couple of new things. First, assert, which just makes sure there isn't some serious bullshit going on with our queue size. I don't think its particularly important, I just thought I'd include it because I saw it somewhere.
Then, our standard loop. What we want from the loop is to go ahead and add produced values to the shared queue, then hold off and allow another thread to run. That's what the yield() method does. Everything else should be self-explanatory.
Here we have the Consumer, which is about as simple as the Producer. We have our globals and then our run(). This "while (true) ..." is an infinite loop, since true is never being changed. This allows the loop to keep running. If we had a variable to run the loop only as many times as the queue in question had values, it wouldn't be able to account for newly added values, which is a bummer.
To solve this infinite loop, though, we just have a break statement if the conditions aren't met (the queue being empty). Otherwise, this is simple, using the yield() when done, and so on.
Tomorrow: Actual testing! Questions/comments welcome etc. See ya!