Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Wiki Markup
Safety and liveness are both concerns when using the wait/notify mechanism.  Safety requires that all objects maintain consistent states in a multithreaded environment \[[Lea 2000|AA. Java References#LeaBibliography#Lea 00]\]. Liveness requires that every operation or method invocation execute to completion without interruption.

...

Wiki Markup
To guarantee safety, the {{while}} loop condition must be tested even after the {{wait()}} method is invoked. While {{wait()}} is meant to block indefinitely until a notification is received, it must still be encased within a loop to prevent the following vulnerabilities \[[Bloch 2001|AA. Java References#BlochBibliography#Bloch 01]\]:

  • thread in the middle - A third thread can acquire the lock on the shared object during the interval between a notification being sent and the receiving thread resuming execution. This thread can change the state of the object, leaving it inconsistent. This is a time-of-check-to-time-of-use (TOCTOU) condition.
  • malicious notification - There is no guarantee that a random notification will not be received when the condition predicate is false. This means that the invocation of wait() may be nullified by the notification.
  • misdelivered notification - Sometimes on receipt of a notifyAll() signal, an unrelated thread can start executing, and it is possible for its condition predicate to be true. Consequently, it may resume execution although it was required to remain dormant.
  • Wiki Markup
    spurious wake-ups - Certain JVM implementations are vulnerable to spurious wake ups that result in waiting threads waking up even without a notification \[[API 2006|AA. Java References#APIBibliography#API 06]\].

For these reasons, the condition predicate must be checked after the wait() method is invoked. A while loop is the best choice for checking the condition predicate before and after invoking wait().

Wiki Markup
Similarly, the {{await()}} method of the {{Condition}} interface must also be invoked inside a loop. According to the Java API \[[API 2006|AA. Java References#APIBibliography#API 06]\], Interface {{Condition}}

...

Wiki Markup
\[[API 2006|AA. Java References#APIBibliography#API 06]\] [Class Object|http://java.sun.com/javase/6/docs/api/java/lang/Object.html]
\[[Bloch 2001|AA. Java References#BlochBibliography#Bloch 01]\] Item 50: Never invoke wait outside a loop
\[[Lea 2000|AA. Java References#LeaBibliography#Lea 00]\] 3.2.2 Monitor Mechanics, 1.3.2 Liveness
\[[Goetz 2006|AA. Java References#GoetzBibliography#Goetz 06]\] Section 14.2, Using Condition Queues

...