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

Ale*_*aer 0 java multithreading thread-safety

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

在同步块中

synchronized(lock) {

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

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

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

synchronized(lock) {

     lock.wait(); //<--- this thread may forever freeze here
}
Run Code Online (Sandbox Code Playgroud)

我无法想象这样的行为(在没有明确通知的情况下在同步块的末尾插入隐式通知)是不合需要的.

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


如何(技术上)实现此类行为可以有不同的方式,例如:

@autonotify
synchronized(lock) {
...
}

@autonotify
public void synchronized doSomething() {
...
}
Run Code Online (Sandbox Code Playgroud)

要么:

@autonotifyAll
synchronized(lock) {
...
}

@autonotifyAll
public void synchronized doSomething() {
...
}
Run Code Online (Sandbox Code Playgroud)

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

@suppressautonotify
synchronized(lock) {
...
}

@suppressautonotifyAll
public void synchronized doSomething() {
...
}
Run Code Online (Sandbox Code Playgroud)

你怎么看?异议?

对该提案的最佳评论将被接受为答案.

JB *_*zet 7

自动或默认执行此操作是一个很大的禁忌.在许多情况下,您在锁上进行同步而不想在同步块的末尾进行通知.这样做会打破很多现有的程序.

为什么要这样做@autonotifyAll而不是lock.notifyAll()在同步块结束时使用简单的方法.如果你忘记打电话lock.notifyAll(),你有很多机会忘记@autonotifyAll.它会降低可读性,降低一致性.

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

如果我必须决定,你的建议将被拒绝.

  • 是的,在99%的情况下,仅在同步时确保互斥.例如,查看java.util.Vector的源代码.它的所有方法都是同步的,并且内部没有调用notify或notifyAll. (2认同)