Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: edits

The methods java.lang.Object.notify() and java.lang.Object.notifyAll() are used to waken waiting thread(s). These methods must be called from code that holds the same object lock as the waiting thread(s).

Any thread that has called invokes wait() expects to wake up and resume execution when some condition predicate becomes true. As recommended by CON18-J. Always invoke wait() and await() methods inside a loop, any waiting thread, when woken, will test its condition predicate, waiting threads should test their condition predicates upon receiving notifications and resume waiting if the predicate has not become true.they are false.

The methods notify() and notifyAll() of package java.lang.Object are used to waken waiting thread(s). These methods must be invoked from code that holds the same object lock as the waiting thread(s)Consequently, the notifyAll() method is recommended rather than the notify() method. The notifyAll() method will wake wakes up all threads , and only threads allows ones whose condition predicate is satisfied will remain awaketrue to resume execution. Furthermore, if all of the threads require a specific lock, only one will obtain the lock, and the others may, presumably, resume waiting. The notify() method wakes up only one thread, and makes no guarantees as to which thread gets woken upis notified. If the thread's condition predicate is not satisifiedsatisfied, the chosen thread may resume waitingnot awaken, defeating the purpose of the notify() call.

The notify() method should may only be called invoked if:

  • Every condition predicate on in every thread waiting on the object is satisfied when a notification is received by each, independently. In other words, any selected thread is allowed to wake up and resume.
  • Only one thread must wake up on the notify signal. This is contingent on the condition predicate, in that, only one predicate must fulfill the condition and allow the thread to proceed. Multiple condition predicates in the same statement should be avoided.
  • No untrusted code has access to the object being waited on. If untrusted code has access to this object, it can wait() on the object and intercept a notify() call.

The java.util.concurrent utilities (interface Condition) provide the signal() and signalAll() methods to awaken waiting threads that are blocked on an await() call. Like the notify() method, the signal() method wakes up any one of the threads that is waiting on the condition and consequently, may be insecure. It is always safer to use signalAll albeit a small performance penalty. Similarly, any thread that is blocked on a wait() method invocation on a Java object being used as a condition queue, should be notified using notifyAll().

...

This noncompliant code example demonstrates shows a complex multi-step process being undertaken by several threads. Each thread executes one step of the process; the step being currently performed is maintained enumerated by the step field. Each thread waits for the step field to indicate that it is time to perform that the corresponding thread's step. When it is time to perform its After performing the step, each thread does so. It then increments step for to transfer control to the next thread, notifies the threadit, and exits.

Code Block
bgColor#FFcccc
public class ProcessStep implements Runnable {
  private static final Object lock = new Object();
  private static int time = 1;
  private int myStepstep; // doDo stuffoperations when the step rachesreaches this value

  public ProcessStep(int myStepstep) {
    this.myStepstep = myStepstep;
  }

  public void run() {
    try {
      synchronized (lock) {
        while (time != myStepstep) { 
          lock.wait();  
        }

        // ... doDo stuffoperations

        time++;
        lock.notify();
      }
    } catch (InterruptedException ie) {
      Thread.currentThread().interrupt(); // Reset interrupted status
    }    
  }

  public static void main(String[] args) {
    for (int i = 5; i > 0; i--) {
      ProcessStep ms = new ProcessStep(i);
      new Thread(ms).start();
    }
  }
}

This noncompliant code example violates the liveness property. Each thread has a different condition predicate, as each requires step to have a different value before proceeding. The Object.notify() method wakes up only one thread at a time; . unless it happens to wake up the thread that is to perform the next step, the program will deadlockdeadlocks.

Compliant Solution (notifyAll())

In this compliant solution, each thread uses all threads that have performed their own step use notifyAll() to wake all of the notify other waiting threads when its step is complete. Consequently the proper thread can perform its next step, the respective threads that are ready can perform the task, while all other threads note that their whose condition predicate has not been satisified and is unsatisfied promptly go back to sleep.

Code Block
bgColor#ccccff

  // ...
  public void run() {
    try {
      synchronized (lock) {
        while (time != myStepstep) { 
          lock.wait();  
        }

        // ... do stuff

        time++;
        lock.notifyAll();
      }
    } catch (InterruptedException ie) {
      Thread.currentThread().interrupt(); // Reset interrupted status
    }    
  }

...

Code Block
bgColor#FFcccc
public class ProcessStep implements Runnable {
  private static final Lock lock = new ReentrantLock();
  private static final Condition condition = lock.newCondition();
  private static int time = 1;
  private int myStepstep; // doDo stuffoperations when the step rachesreaches this value

  public ProcessStep(int myStepstep) {
    this.myStepstep = myStepstep;
  }

  public void run() {
    lock.lock();
    try {
      while (time != myStepstep) { 
        condition.await();  
      }

      // ... doDo stuffoperations

      time++;
      condition.signal();
    } catch (InterruptedException ie) {
      Thread.currentThread().interrupt(); // Reset interrupted status
    } finally {
      lock.unlock();
    }
  }

  public static void main(String[] args) {
    for (int i = 5; i > 0; i--) {
      ProcessStep ms = new ProcessStep(i);
      new Thread(ms).start();
    }
  }
}

Similar to Object.notify(), the condCondition.signal() method may choose any one thread and awaken it.

...

Code Block
bgColor#ccccff
  public void run() {
    lock.lock();
    try {
      while (time != myStepstep) { 
        condition.await();  
      }

      // ... do stuff

      time++;
      condition.signalAll();
    } catch (InterruptedException ie) {
      Thread.currentThread().interrupt(); // Reset interrupted status
    } finally {
      lock.unlock();
    }
  }

...

Code Block
bgColor#ccccff
public class ProcessStep implements Runnable {
  private static final Lock lock = new ReentrantLock();
  private static final Condition[] conditions = new Condition[6];
  private static int time = 1;
  private int myStepstep; // doDo stuffoperations when the step rachesreaches this value
  private static final Condition[] conditions = new Condition[step];

  public ProcessStep(int myStepstep) {
    this.myStepstep = myStepstep;
    conditions[myStepstep] = lock.newCondition();
  }

  public void run() {
    lock.lock();
    try {
      while (time != myStepstep) { 
        conditions[myStepstep].await();  
      }

      // ... doDo stuffoperations

      time++;
      if (myStepstep + 1 < conditions.length) {
        conditions[myStepstep + 1].signal();
      }
    } catch (InterruptedException ie) {
      Thread.currentThread().interrupt(); // Reset interrupted status
    } finally {
      lock.unlock();
    }
  }

  public static void main(String[] args) {
    for (int i = 5; i > 0; i--) {
      ProcessStep ms = new ProcessStep(i);
      new Thread(ms).start();
    }
  }
}

...