The methods {{ Wiki Markup 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). The method {{notify()}} is deceptive in most cases unless all of the following conditions hold: \[[Goetz 06|AA. Java References#Goetz 06]\]
Any thread that has called wait()
expects to wake up 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, and resume waiting if the predicate has not become true.
Consequently, the notifyAll()
method is recommended rather than the notify()
method. The notifyAll()
method will wake up all threads, and only threads whose condition predicate is satisfied will remain awake. 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 up. If the thread's condition predicate is not satisified, the chosen thread may resume waiting, defeating the purpose of the notify()
call.
The notify()
method should only be called if
- Every condition predicate on every thread waiting on the object is satisfiedOnly one condition predicate is used with the locked object. Also, each thread must execute the same code after waking up from a wait.
- 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.
...
- 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 anotify()
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.
...
Even though signal()
is used, it is guaranteed that only one thread will awaken because each condition predicate corresponds to a unique Condition
variable.
Exceptions
EX1: If there are several similar threads waiting for a notification, and it is permissible to invoke any of them, notify()
may be used. The criteria for liveness is relaxed in this case.
Risk Assessment
Invoking the notify()
method instead of notifyAll()
can be a threat to the liveness property of the system.
...