notify instead of notifyAll¶
ID: java/notify-instead-of-notify-all
Kind: problem
Security severity:
Severity: warning
Precision: medium
Tags:
- reliability
- correctness
- concurrency
- external/cwe/cwe-662
Query suites:
- java-security-and-quality.qls
Click to see the query in the CodeQL repository
Calls to the notify
method rather than notifyAll
may fail to wake up the correct thread if an object’s monitor (intrinsic lock) is used for multiple conditions. notify
only wakes up a single arbitrary thread that is waiting on the object’s monitor, whereas notifyAll
wakes up all such threads.
Recommendation¶
Ensure that the call to notify
instead of notifyAll
is a correct and desirable optimization. If not, call notifyAll
instead.
Example¶
In the following example, the methods produce
and consume
both use notify
to tell any waiting threads that an object has been added or removed from the buffer. However, this means that only one thread is notified. The woken-up thread might not be able to proceed due to its condition being false, immediately going back to the waiting state. As a result no progress is made.
class ProducerConsumer {
private static final int MAX_SIZE=3;
private List<Object> buf = new ArrayList<Object>();
public synchronized void produce(Object o) {
while (buf.size()==MAX_SIZE) {
try {
wait();
}
catch (InterruptedException e) {
...
}
}
buf.add(o);
notify(); // 'notify' is used
}
public synchronized Object consume() {
while (buf.size()==0) {
try {
wait();
}
catch (InterruptedException e) {
...
}
}
Object o = buf.remove(0);
notify(); // 'notify' is used
return o;
}
}
When using notifyAll
instead of notify
, all threads are notified, and if there are any threads that could proceed, we can be sure that at least one of them will do so.
References¶
J. Bloch. Effective Java (second edition), p. 277. Addison-Wesley, 2008.
Java API Specification: Object.notify(), Object.notifyAll().
Common Weakness Enumeration: CWE-662.