问题
I have been thinking of send a proposal to the Java language architects.
In a synchronized block
synchronized(lock) {
// If there is no notification before this point
// <--- implicitly put here // lock.notifyAll(); // OR // lock.notify();
}
After a thread left synchronized block, it cannot call lock.notifyAll() / lock.notify() anymore without getting exception.
Forgetting to notify other thread monitor holders may forever make them (other threads) wait (unless, they put some timeout in their wait method).
synchronized(lock) {
lock.wait(); //<--- this thread may forever freeze here
}
I cannot imagine a situation in which such behavior (inserting implicit notification at the end of a synchronized block, when there is no explicit notification) is undesirable.
The same approach can be applied to synchronized methods.
There can be different ways how to (technically) implement such behavior, for example:
@autonotify
synchronized(lock) {
...
}
@autonotify
public void synchronized doSomething() {
...
}
Or:
@autonotifyAll
synchronized(lock) {
...
}
@autonotifyAll
public void synchronized doSomething() {
...
}
Or - make auto-notification the default behavior, but leaving ability to suppress it, for example:
@suppressautonotify
synchronized(lock) {
...
}
@suppressautonotifyAll
public void synchronized doSomething() {
...
}
What do you think? Objections?
The best commentary for or against the proposal will be accepted as the answer.
回答1:
Doing it automatically or by default is a big no-no. There are many situations where you synchronize on a lock without wanting to notify at the end of the synchronized block. Doing so would break a whole lot of existing programs.
And why do it with @autonotifyAll
instead of doing it with a simple lock.notifyAll()
at the end of the synchronized block. If you forget to call lock.notifyAll()
, you have as many chances to forget @autonotifyAll
. And it would make things less readable, and less consistent.
The best practice, anyway, is to avoid using these very low-level methods, and to use higher-level abstractions, like blocking queues, countdown latches, semaphores, etc.
If I had to decide, your suggestion would be rejected.
回答2:
Object.wait
and Object.notify/All
are considered pretty low-level mechanisms for synchronization; most of the time, you'll want to use higher-level constructs like those found in java.util.concurrent or its sub-packages. If your use case is subtle or special enough that you need to use these Object
methods rather than the higher-level tools that the JDK people have built, tested and optimized for you -- well then, you probably want full control, and hopefully (for the users of your code) you can handle it.
To use a driving metaphor, this question is the equivalent of buying a car with a manual transmission instead of an automatic, and then asking the car manufacturer to automatically work the clutch for you when you want to switch gears.
来源:https://stackoverflow.com/questions/15886972/automatic-notify-notifyall-on-leaving-a-synchronized-block