The wait() and notify() methods must be called from inside a synchronized block (synchronized on the object you call wait() and notify() on) ie. the current thread must own the object's monitor = object's lock.
The locks to the objects you call wait() and notify() on have to be owned by the thread which calls those methods - which means you have to put those calls in a synchronized block:
There are other alternatives which may make better sense to use in this scenario (and be easier to implement). Things that come to mind would be a BlockingQueue implementation (a SynchronousQueue maybe), a Semaphore, an Exchanger, CyclicBarrier ... It depends on the semantics of communication between the two Threads (1-1 signaler to receiver, do they both have to hit the point at the same time, can the signaler preemptively tell the receiver it can go, is there actual data to exchange, etc...)
Adam Michalik wrote:The wait() and notify() methods must be called from inside a synchronized block (synchronized on the object you call wait() and notify() on) ie. the current thread must own the object's monitor = object's lock.
And of course, just adding the synchronization may only solve the symptom. Keep in mind that the requirement of owning the lock wasn't just added to be annoying. There are race conditions that can't be solved, if the wait() method didn't release the lock for you. So, it would be a good idea to understand how to use it too.
In case when idleCount ==0 && isFull() == true you dont start a new thread, but simply exit returning true.
You don't show here how isFull() works and where idleCount is changed.
I guess that this condition should never happen ..... but who knows ;)
Change this fragment into:
and run your programm with assertion enabled.
BTW, in this code fragment:
'if' and 'break' is unnecessary (you have the same condition in the while loop).