小编典典

离开同步块时自动notify()/ notifyAll()

java

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

在同步块中

synchronized(lock) {

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

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

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

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() {
...
}

你怎么看?有异议吗

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


阅读 316

收藏
2020-11-30

共1个答案

小编典典

自动或默认情况下这样做是很大的禁忌。在许多情况下,您在锁上进行同步而不希望在已同步块的末尾进行通知。这样做会破坏很多现有程序。

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

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

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

2020-11-30