First of all, I have to admit that I posted this question on Sun Forums earlier. But since Oracle acquisition of Sun, forums seem to be dead, and there's a little chance to get a response there. Every time I log in, I see "0 Users online". So, I do respect JavaRanch community, and therefore apologize for having to copy-paste my original post. Thank you for understanding.
I spent considerable amount of time today trying to figure out what I'm doing wrong to no avail. Sorry for such long code, but I see no way to reduce it. And also, please, do not point at design flaws - I do know that from the point of OO it's not semantically correct to declare Producer and Consumer as inner classes of a single class and such. It doesn't matter here. I'm just trying to understand why it doesn't work. So, in first call to wait Consumer releases lock on prod object. Then Producer
thread enters synchronized block (acquires a lock on the prod object). However, after call to notify and exiting synchronized block (therefore releasing a lock), it doesn't wake the Consumer up for no apparent reason (well, in fact it does occasionally, once per 10 loops). Moreover, when I uncomment a line right after Consumer synchronized block, which outputs "Producer should have released lock by now" to console, the behavior changes a bit. Consumer starts to consume values, but again, asynchronously and in chaotic manner. Could anybody clarify what is wrong in this code? Any help would be highly appreciated.
P.S. Also, don't worry about main method inside nested class. After reading Bruce Eckel's "Thinking in Java" I figured it's really neat to have main, designed for
testing purposes only, inside a nested class, which you could physically remove from your hard drive after testing is done. And I do invoke main correctly as following:
java threads.WaitDemo$Tester.
So here is the code: