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

后端 未结 7 1536
生来不讨喜
生来不讨喜 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:12

    Good question. The comments in the JDK7 Object implementation shed some light on this, I think (emphasis mine):

    This method causes the current thread (call it T) to place itself in the wait set for this object and then to relinquish any and all synchronization claims on this object.

    ...

    The thread T is then removed from the wait set for this usual manner with other threads for the right to synchronize on the object; once it has gained control of the object, all its synchronization claims on the object are restored to the status quo ante - that is, to the situation as of the time that the wait method was invoked. Thread T then returns from the invocation of the wait method. Thus, on return from the wait method, the synchronization state of the object and of thread T is exactly as it was when the wait method was invoked.

    So I think the first point to note is that wait() doesn't return until the caller is done waiting (obviously). Meaning that if wait() itself were synchronized then the caller would continue to hold the lock on the object, and nobody else would be able to wait() or notify().

    Now obviously wait() is doing something tricky behind the scenes to force the caller to lose its ownership of the lock on the object anyways, but perhaps this trick would not work (or would be significantly more difficult to make work) if wait() itself were synchronized.

    The second point is that if multiple threads are waiting on an object, when notify() is used to wake exactly one of them the standard contention method is used to allow only one thread to synchronize on the object, and that wait() is supposed to restore the caller's synchronization claims to the exact state they were in prior to the call to wait(). It seems possible to me that requiring the caller to hold the lock prior to calling wait() simplifies this, as it removes the need to check to see if the caller should or should not continue holding the lock after wait() returns. The contract stipulates that the caller must continue holding the lock, and thus some of the implementation is simplified.

    Or perhaps it was simply done to avoid the appearance of the logical paradox of "if wait() and notify() are both synchronized, and wait() doesn't return until notify() is called, how can either ever be used successfully?".

    Those are my thoughts, anyways.

提交回复
热议问题