当前位置: 首页 > 面试题库 >

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

年文柏
2023-03-14
问题内容

我一直在考虑向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() {
...
}

你怎么看?有异议吗

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


问题答案:

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

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

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

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



 类似资料:
  • 问题内容: 我了解到,调用对象的方法将释放对象监视器(如果存在)。 但是我对通过另一个线程调用该对象有一些疑问: (何时)等待线程唤醒,如果同时有另一个(第3个)线程拥有对象监视器? 如果在该对象上调用了第三个线程,等待线程将被唤醒吗? 是否可以确定线程是否正在等待通知特定对象(java 1.4 / java 5) 如果将在方法中调用会发生什么情况? 问题答案: 将唤醒在监视器上等待的一个线程。除

  • 问题内容: 我正在尝试检查java中的wait / notify如何工作。 码: 输出返回 我期望在执行notify()时,等待将结束并被打印。但似乎只有完成打印后才能打印。 问题答案: 对象监视器锁需要执行相同锁的单个引用。 在你的榜样,你是对的一个实例,但使用从。相反,您应该使用单个通用锁定对象…例如 输出… 并可能根据线程调度更改位置。 您可以尝试将睡眠排除在障碍之外。这将释放监视器锁定,从

  • 问题内容: 我是在Java中使用wait()和notify()的新手,并且遇到了IllegalMonitorStateException。 主要代号 我收到一个IllegalMonitorStateException,称为state.notify()。有任何想法吗? 编辑 :根据下面的答案是有效的代码。作为附带说明,我首先尝试使用与使用Integer相同的问题的枚举进行此操作。 问题答案: 这个

  • 我正在学习 处等待(由于< code > synchronized ,它从未进入其代码块)。一旦生产者线程退出它的同步代码块,消费者线程将进入它的。现在,队列是非空的,因为生产者只是在通知之前放了一些东西进去。消费者线程将移除它,调用notify,退出它的块,此时生产者将获得锁,因为它现在已经在生产者函数中的< code>synchronized(lock)行等待。三个问题: > < li> 在我

  • Java中,任何对象都可以作为锁,并且 wait(),notify()等方法用于等待对象的锁或者唤醒线程,在 Java 的线程中并没有可供任何对象使用的锁,所以任意对象调用方法一定定义在Object类中。 wait(), notify()和 notifyAll()这些方法在同步代码块中调用 有的人会说,既然是线程放弃对象锁,那也可以把wait()定义在Thread类里面啊,新定义的线程继承于Thr

  • 问题内容: 我正在查看包含同步方法的第三方库中的一些代码,在此方法中,有一个锁定在实例变量上的同步块。与此类似: 这有意义吗?如果是这样,在同步方法中使用同步语句有什么好处? 鉴于同步方法锁定了整个对象,对我来说似乎是多余的。在使用非私有的实例变量时,这种方法是否有意义? 问题答案: 在您的示例中,该方法 同时 锁定了和的实例。其他方法可能仅锁定对象的实例 或 对象。 因此,是的,这完全取决于他们