markiz
markiz

Reputation: 2184

wait and notify coordination

There is a main thread that has a while loop, in this while he checks for some conditions and if all conditions are met he starts another threads enters wait() state.

Other threads that run in parallel notify the main thread upon work completion.

There is a problem when "sub thread" notifies the main thread before the main thread enters the wait state = dead lock.

What is the best practice to avoid it?

Upvotes: 1

Views: 182

Answers (5)

Surender Thakran
Surender Thakran

Reputation: 684

It is a very common practice to almost always put the wait() method in a while loop whose "iteration condition" is to check whether a particular event has occurred, on occurrence of which the other thread would have called the notify() method.

ex:

while(!event_occurrence) {
    ...
    wait();
    ...
}

where event_occurrence is the event on which the other thread would have called notify() method.

Upvotes: 0

akhilss
akhilss

Reputation: 131

The easy answer is to use the concurrency package in Java 5. A CountDownLatch seems suitable here.

If you are limited to a pre Java 5 environment, you will have to create a custom implementation which uses the same algorithm. The main thread would call signalReady after creation of all child threads. The child threads would call signalComplete after completing their work.

A simple implementation would be to have an Object called a Latch with two two member fields.

The below implementation will work for one parent and one child. For additional children, each child could be given its own latch to signal when complete. There would still be cases where this will be race conditions. Adding a spin lock or maybe a sleep between the signalling would reduce the probability of a race conditions. It would not eliminate it

class Latch{
  Object readyLock;
  Object completeLock;

  public void signalComplete(){
    synchronized(readyLock){
      readyLock.wait()
    }
    //spin lock as a precaution
    synchronized(completeLock){
      completeLock.notify()
    }
  }

  public void signalReady(){
    synchronized(readyLock){
      readyLock.notify()
    }
    synchronized(completeLock){
      completeLock.wait()
    }
  }
}

Hope this helps!

Upvotes: 0

Martin James
Martin James

Reputation: 24847

Use a semaphore for the notification.

That's it, really. A semaphore has a count and can record the notification until the main thread gets around to waiting on it.

Upvotes: 0

amicngh
amicngh

Reputation: 7899

I would prefer to use Explicit Locks. See Java Concurrent Api.

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/Lock.html

Upvotes: 0

David Schwartz
David Schwartz

Reputation: 182763

Just make sure the main thread doesn't wait for something that has already happened. (Why would anyone do that anyway? It makes no sense.)

Upvotes: 1

Related Questions