|
Re: Thread waiting.
notify() and wait() are methods of the Object class, which all other classes ultimately inherit from. You can call notify() and wait() on any object.
It is supposed to play out like this
Given an object A. A is shared between multiple threads.
1. Thread 1 needs to use A, so it acquires a lock, with a synchronized block (synchronized keyword doesn't just apply to methods). Let's assume the lock is already available, so this occurs instantly. Thread 1 can now safely call methods on and otherwise manipulate object A, because any other thread that attempts to lock object A during this time will block until the lock is released.
2. Thread 1 determines that it needs to wait for more data to arrive/for some event to occur. It calls A.wait(). Not just wait() -- calling wait() would wait() on 'this', which is thread 1. The reason A.wait() is called is because A is the object for which the lock was acquired. Calling wait() releases the lock and says "I don't want it back...YET"
3. Thread 2 comes along. It acquires the lock instantly because thread 1 released it. Some important thing happens, so it calls notify(). A single thread (thread 1 in this case) is no longer waiting. It goes from "don't want it yet" to "done waiting, give me the lock back." When thread 2 gives up the lock, by calling wait() or exiting the synchronized block/method, thread 1 can grab the lock and continue running - right where it left off, and (depending on your implementation and needs) the waiting condition may be assumed to have been met.
In your code:
You have two run methods, each of which is marked synchronized. This is more or less a shortcut for putting synchronized(this) { } inside the method. As in, instanceOfParent.run() attempts to lock instanceOfParent. instanceOfChild.run() locks instanceOfChild. When you call wait() or notify(), you are implying this.wait() and this.notify(). You are waiting and notifying two separate objects. Neither case throws an exception because each run() method locks this due to the synchronized keyword.
Let's say that the initial bag state is that it contains 1 sweet and avail is true. When you call wait() in the Parent class, it will never wake up because notify() will never be reached. In the Child class, one sweet will be removed and avail will be set to false. It will then call notify(), which will notify *the child*. However, no threads are waiting on the child. At the top of the loop, wait() will be called. Both threads are waiting at this point, with no thread to wake them up.
An object that needs to be locked is one that is shared between multiple threads. You probably intended to lock 'bag.' You should wrap most of your run() methods in a synchronized(bag) { } block and call bag.wait() and bag.notify().
I can comment further if you want when you get it working. It takes a while to get your head around it.
__________________
MD5(sig) = bcef75433db02e9ad9bf81d6f7c5c270
|