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="e289e4e7d90de7e9-efd49673-4ba3418d-b2eb8a16-758e4d84c057ae7864ca304e"><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="bd7103f672ae3554-a17baffc-44e946d6-b5d8b0d8-dababc3895d11c42ab8a5269"><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="85cc062101f64924-bd2316ef-4ebe46c1-8b39943c-9ec3858eff59a41d41fb94dc"><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="d0f120019f6a659d-daf0a6b9-490d4a95-a1d08045-38de9782ade4c68f9c4ed651"><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>

...