the problem is here:
synchronized(p1) { p2.cont = true; p2.notify(); }
You execute p2.notify() when you do not have a lock on p2 (you must hold the monitor to trigger a notification about this). Change synchronized(p1) to synchronized(p2) . In addition, you also need to cancel another synchronized offer, which is also defective. So, as an example:
synchronized(p1) { p1.cont = false; // p1.notify(); <- do you need this here? } table.removeAll(); synchronized(p2) { p2.cont = true; p2.notify(); }
Also, your other code is also a bit wrong, a very bad practice of locking inside an entire loop, make it a little more atomic.
while (!cont) { synchronized (this) { try { wait(); } catch (Exception e) { } } }
Additional optimization, avoid synchronised if possible:
if (p1.cont) { synchronized(p1) { p1.cont = false; // p1.notify(); <- do you need this here? } } table.removeAll(); if (!p2.cont) { synchronized(p2) { p2.cont = true; p2.notify(); } }
Make a cont volatile field here and a mirror for the other part of the if statement, if necessary.
Edit: Looking back and battling with the concurrency error that I recently encountered, anyone who implements this template may encounter an endless wait problem if an object locked and half-locked is being scanned for the while loop condition (this is because there is a space, in which the state can change between the evaluation of the conditional and the imposition of the wait operator) In this case, place the synchronized block outside the loop.
source share