Versions Compared

Key

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

...

Wiki Markup
Both safety and liveness are concerns when using the wait/notify mechanism. The safety property requires that all objects maintain consistent states in a multithreaded environment \[[Lea 2000|AA. Bibliography#LeaReferences#Lea 00]\]. The liveness property requires that every operation or method invocation execute to completion without interruption.

...

Wiki Markup
To guarantee safety, programs must test the {{while}} loop condition after returning from the {{wait()}} method. Although {{wait()}} is intended to block indefinitely until a notification is received, it must still be encased within a loop to prevent the following vulnerabilities \[[Bloch 2001|AA. Bibliography#BlochReferences#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 third thread can change the state of the object, leaving it inconsistent. This is a TOCTOU race condition.
  • Malicious notification — A random or malicious notification can be received when the condition predicate is false. Such a notification would cancel the wait().
  • Misdelivered notification — The order in which threads execute after receipt of a notifyAll() signal is unspecified. Consequently, an unrelated thread could start executing and discover that its condition predicate is satisfied. Consequently, it could resume execution, although it was required to remain dormant.
  • Wiki Markup
    Spurious wakeups --- Certain JVM implementations are vulnerable to spurious wakeups that result in waiting threads waking up even without a notification \[[API 2006|AA. Bibliography#APIReferences#API 06]\].

For these reasons, programs must check the condition predicate after the wait() method returns. A while loop is the best choice for checking the condition predicate both 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. Bibliography#APIReferences#API 06]\], Interface {{Condition}}

...

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="1ed30972d54146c1-b702b5b5-461d4f51-892eac1e-094956c73c5df238c34d9de7"><ac:plain-text-body><![CDATA[

[[API 2006

AA. Bibliography#API References#API 06]]

[Class Object

http://java.sun.com/javase/6/docs/api/java/lang/Object.html]

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="382b6afda3a2d1ee-a92799d1-49a84eea-b722ac4f-a2a15b6285e56ae38fdb3fd0"><ac:plain-text-body><![CDATA[

[[Bloch 2001

AA. Bibliography#Bloch References#Bloch 01]]

Item 50. Never invoke wait outside a loop

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="71a17f2cbf732815-18aa4d1e-48794cfa-a438bb2c-2f4721f3e3796aa39d2895e8"><ac:plain-text-body><![CDATA[

[[Lea 2000

AA. Bibliography#Lea References#Lea 00]]

3.2.2, Monitor Mechanics; 1.3.2, Liveness

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="b0f77f54f7cd7e53-0e7e7062-4306425f-a330aa00-8e6752e8b64126b6b67ea06f"><ac:plain-text-body><![CDATA[

[[Goetz 2006

AA. Bibliography#Goetz References#Goetz 06]]

Section 14.2, Using Condition Queues

]]></ac:plain-text-body></ac:structured-macro>

...