why wait/notify/notifyAll methods are not synchronized in java ?

后端 未结 7 1529
生来不讨喜
生来不讨喜 2020-12-05 10:20

in Java whenever we need to call wait/notify/notifyAll, we need to have access to object monitor (either through synchronized method or through synchronized block). So my q

相关标签:
7条回答
  • 2020-12-05 11:17

    The wait-notify model of synchronization requires that you acquire the monitors on an object first, before proceeding to perform any work. It is different from the mutual exclusion model that is used by a synchronized block.

    The wait-notify or mutual cooperation model is typically used in a producer-consumer scenario where one thread produces events that are consumed by another thread. Well-written implementations will strive to avoid the scenarios where a consumer is starved or the producer overruns the consumer with too many events. To avoid this, you would use the wait-notify protocol where

    • the consumer waits for the producer to produce an event.
    • the producer produces the event and notifies the consumer, and then usually goes to sleep, until it is notified by the consumer.
    • when the consumer is notified of an event, it wakes up, processes the event and the notifies the producer that it has finished processing the event.

    You could have many producers and consumers in this scenario. Acquiring the monitor through the mutual exclusion model, on wait, notify or notifyAll is bound to destroy this model, since the producer and the consumer do not perform the waiting explicitly. The underlying threads will be present in either the wait set (used by the wait-notify model) or the entry set (used by the mutual exclusion model) of a monitor. Invoking notify or notifyAll signals thread(s) to be moved from the wait set to the entry set of the monitor (where there may be contention for the monitor, among several threads, and not just the recently notified one).

    Now, when you want to automatically acquire the monitor on wait, notify and notifyAll using the mutual exclusion model, it is usually an indication that you do not need to be using the wait-notify model. This is by inference - you would typically signal other threads, only after doing some work in one thread, i.e. on a change in state. If you are automatically acquiring the monitor and invoking notify or notifyAll, you are merely moving threads from the wait set to the entry set, without any intermediate state in your program, implying that the transition is unnecessary. Quite obviously, the authors of the JVM were aware of this, and have not declared the methods as synchronized.

    You can read more about the wait sets and entry sets of monitors in Bill Venner's book - Inside the Java Virtual Machine.

    0 讨论(0)
提交回复
热议问题