You want to use a counting semaphore. Condition variables are used to schedule flows within the monitor. This is not what you are trying to do.
You create a counting semaphore and set the counter to zero
// create a counting semaphore with an initial count of zero java.util.concurrent.Semaphore s = new java.util.concurrent.Semaphore(0);
You pass the semaphore to your class whether the processing does. When it is completed, it will increment the counter to 1 by calling s.release() .
To block the thread until processing is complete, you call s.aquire() . This call will block your other thread until the processor calls s.release() .
This is the simplest solution.
Btw, s.aquire() and s.release() are thread safe, so you do not need to use the synchronize keyword. Topics can share semaphore references and call its methods without blocking.
UPDATE:
I am going to answer your comment here, and not make a new comment.
Yes, in your case, the wait () / notify () solution is similar to using a semaphore. To rewrite the rsp solution using a semaphore, it would look like this:
java.util.concurrent.Semaphore s = new java.util.concurrent.Semaphore(0); public setDone() { s.release(); } public waitUntilDone() { s.aquire(); }
This is much simpler and you do not need unnecessary locking (note that I removed the synchronized keyword from the decs method.).
There are two differences between state variables (wait () / notify ()) and semaphores.
Difference # 1: notify () calls may be lost, release () calls are never lost
The first difference is that notify () calls are lost if there is no waiting thread through the wait () call. The work around is to check the state before calling wait (). Basically, we need to remember that notify () is called with a shared variable, so we do not accidentally call wait () after the worker calls notify (), or we are stuck. Counting semaphores works regardless of the order in which the receive () and release () functions are called, since they support the count internally.
Difference # 2: calls to wait () automatically release the lock, calls acquire () do not
Some reference data will help here. In your program, boolean done = false; variable is a condition, but it is not a condition variable. I know confusing terminology. A condition variable is a variable that has wait () and notify () operations. Each object in Java has a condition variable hidden inside and a corresponding lock.
All condition variables are associated with a lock. You must acquire a lock before you can call wait () and notify () (you will get an exception at runtime, if you don't, try). Once the lock is received, calls to wait () will automatically release the lock, allowing another thread inside the monitor, possibly calling notify (). Sometimes this is exactly what you want, and trying to mimic this behavior with semaphores will be a lot harder.
Note. I use the academic definition of a monitor, which is completely different from the definition of a Java monitor.