Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 离开同步块时自动通知()/notifyAll()_Java_Multithreading_Thread Safety - Fatal编程技术网

Java 离开同步块时自动通知()/notifyAll()

Java 离开同步块时自动通知()/notifyAll(),java,multithreading,thread-safety,Java,Multithreading,Thread Safety,我一直在考虑向Java语言架构师发送一份提案 在同步块中 synchronized(lock) { // If there is no notification before this point // <--- implicitly put here // lock.notifyAll(); // OR // lock.notify(); } 或: 或-使自动通知成为默认行为,但保留抑制该行为的功能,例如: @autonotify synchronized(lock) { ...

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

在同步块中

synchronized(lock) {

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

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

@autonotify
synchronized(lock) {
...
}

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

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

你觉得怎么样?反对意见


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

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

为什么要使用
@autonotifyAll
而不是在同步块的末尾使用简单的
锁。notifyAll()。如果忘记调用
lock.notifyAll()
,那么忘记
@autonotifyAll
的机会同样多。这会让事情变得不那么可读,也不那么一致

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


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

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


用驾驶比喻来说,这个问题相当于买一辆手动变速器而不是自动变速器的汽车,然后当你想换档时,让汽车制造商为你自动操作离合器。

在很多情况下,这样做会导致错误(或至少在等待条件未满足时不需要的唤醒)。并不是所有的同步都是为了通知监视器。我也是这么想的-将行为更改为auto nofity会破坏现有的应用程序。这可能是不这样做的主要原因。但是,问题仍然存在-您能想象在没有notify()或notifyAll()的情况下离开同步块的情况吗是的,在99%的情况下,同步只是为了确保互斥。例如,看看java.util.Vector的源代码。它的所有方法都是同步的,并且内部没有对notify或notifyAll的调用。autonotifyAll和lock.notifyAll()之间的区别如果抛出异常,lock.notifyAll()可能会被跳过,但autonotifyAll的实现方式可能类似于finally块行为。@AlexKreutznaer已经有了一种方法来执行synchronized(lock){}finally{}。它只是与您想要的语法略有不同:
synchronized(lock){try{…}finally{…}
完全脱离主题,但今天市场上的许多汽车都有“拨片式换档器”,可以做到这一点!;-)(尽管承认它们不是手动变速器)
@autonotifyAll
synchronized(lock) {
...
}

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

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