Hi Marlene
I agree with you this question is really interesting. Sometime back I thought about this thing and then after getting no concrete answer just left the question.
(3) In truth, I could not explain above why notify must be synchronized. After all, when the second thread notifies the waiting thread(s) and then exits the synchronized block, another thread could change the condition again before the notified thread(s) is scheduled to run again.
Now I know why. The waiting thread of course has to be synchronized, so that the state of the object does not change between the time the condition is checked and the code after the condition executes. Therefore, all methods reading or changing the condition must be synchronized. Otherwise the first thread might test the condition, then the second thread in an unsynchronized method changes the condition and calls notify that is ignored, then the first thread calls wait and misses the notification.
I still don't understand why notify must be synchronized. As you just said it is very much possibe that the first thread calls notify and the second thread that should now execute doesn't executes and instead a third thread executes and causes the data to be changed which is to be used by the second thread.
Otherwise the first thread might test the condition, then the second thread in an unsynchronized method changes the condition and calls notify that is ignored, then the first thread calls wait and misses the notification.
Here is the first thread synchronized? If yes then the second thread can not change the condition if the lock is obtained on the condition(which should be done) unless wait is called(or somehow the lock is released). Now when wait() has been called then the second unsynchronized thread's notify should be acknowledged.
In case the first thread is not synchronized then the condition can change anytime during the course of the execution of the program.
I am attaching an application that does the following :
1. Producer produces the output. Producer is synchronized.
2. Consumer should consume the output. Consumer is synchronized.
3. Sometimes the hijacker steps in and changes the output. Hijacker is not synchronized.
What should happen is producer should produce and then issue a wait. Then consumer should consume and then it should also issuse a wait and notify the producer. But sometimes what happens is hijacker thread comes in between and changes the output to something else. This happens when producer has produced and is waiting for consumer for consume.
But I don't understand why hijacker though having a priority of 10 only comes into play a very limited no. of times. So you may have to run this application a few times before actually getting to the desired output.