0

我一直在考虑向 Java 语言架构师发送提案。

在同步块中

synchronized(lock) {

// If there is no notification before this point
// <--- implicitly put here // lock.notifyAll(); // OR // lock.notify();  
}

线程离开同步块后,它不能再调用 lock.notifyAll() / lock.notify() 而不会出现异常。

忘记通知其他线程监视器持有者可能会永远让他们(其他线程)等待(除非他们在他们的等待方法中设置了一些超时)。

synchronized(lock) {

     lock.wait(); //<--- this thread may forever freeze here
}

我无法想象这种行为(在同步块的末尾插入隐式通知,当没有显式通知时)是不可取的情况。

相同的方法可以应用于同步方法。


如何(技术上)实现这种行为可能有不同的方法,例如:

@autonotify
synchronized(lock) {
...
}

@autonotify
public void synchronized doSomething() {
...
}

或者:

@autonotifyAll
synchronized(lock) {
...
}

@autonotifyAll
public void synchronized doSomething() {
...
}

或者 - 使自动通知成为默认行为,但保留抑制它的能力,例如:

@suppressautonotify
synchronized(lock) {
...
}

@suppressautonotifyAll
public void synchronized doSomething() {
...
}

你怎么看?反对?

支持或反对该提案的最佳评论将被接受为答案。

4

2 回答 2

8

自动或默认执行此操作是一个很大的禁忌。在许多情况下,您在锁上同步而不希望在同步块结束时通知。这样做会破坏大量现有程序。

以及为什么要在同步块的末尾@autonotifyAll使用简单的而不是这样做。lock.notifyAll()如果你忘记打电话lock.notifyAll(),你有很多机会忘记@autonotifyAll。它会使事情变得不那么可读,也不那么一致。

无论如何,最好的做法是避免使用这些非常低级的方法,而使用更高级别的抽象,如阻塞队列、倒计时锁存器、信号量等。

如果我必须做出决定,您的建议将被拒绝。

于 2013-04-08T19:14:19.807 回答
0

Object.wait并且Object.notify/All被认为是相当低级的同步机制;大多数时候,您会想要使用更高级别的构造,例如java.util.concurrent或其子包中的构造。如果您的用例足够微妙或特殊,以至于您需要使用这些Object方法,而不是 JDK 人员为您构建、测试和优化的高级工具——那么,您可能想要完全控制,并且希望(对于您的代码的用户)您可以处理它。

打个开车的比喻,这个问题就相当于买了一辆手动挡而不是自动挡的车,然后在你想换挡的时候让汽车制造商自动为你工作离合器。

于 2013-04-08T19:26:58.553 回答