在并发Java程序中非标准使用wait notify
我非常熟悉在并发Java程序中非标准使用wait notify,java,multithreading,design-patterns,wait,notify,Java,Multithreading,Design Patterns,Wait,Notify,我非常熟悉wait()/notify()信令方案在Java中的工作原理。然而,我意识到,我所看到的少数使用模式是该方案的变体,或者是一个应用程序的实现。我还看到了一些众所周知的并发问题的实现,例如用餐哲学家使用wait/notify,但显然是出于教学目的 此外,所有方案都遵循了良好的建议,即始终在循环内调用wait(),并且只在传递循环后更改某些共享变量,如下代码所示: synchronized(mon) { // #CP1 - Do not change variables here
wait()/notify()
信令方案在Java中的工作原理。然而,我意识到,我所看到的少数使用模式是该方案的变体,或者是一个应用程序的实现。我还看到了一些众所周知的并发问题的实现,例如用餐哲学家使用wait/notify,但显然是出于教学目的
此外,所有方案都遵循了良好的建议,即始终在循环内调用wait()
,并且只在传递循环后更改某些共享变量,如下代码所示:
synchronized(mon) {
// #CP1 - Do not change variables here
while !(mycondition) {
try{
// #CP2 Do not change variables here
mon.wait();
} catch(catch (InterruptedException e) { e.printStackTrace(); }
}
// Condition satisfied - Now you can change!
makeOperation();
// Tell others that you're done and exit
mon.notifyAll();
}
我的问题是:wait()/notify()?你是否曾以非正统的方式使用过它?为什么?以下是一些更为具体的问题:
您是否见过在退出循环之前更改共享变量的实现?在我的示例中,是否有理由在控制点#CP1
和#CP2
中分配某些内容
在某些情况下,您是否选择使用notify()
而不是notifyAll()
?虽然可能会提高性能,但您非常确定这不会导致死锁吗?为什么?
是否存在一些复杂的场景,其中等待条件mycondition
取决于多个线程,例如mycondition=a_ready&&b_ready&&c_ready
当然。一个例子是,在CP1,你可以保留一份“等待名单”。我不确定我是否能想到您可能在#CP2改变的共享状态,因为通常情况下,while循环只有在“虚假”唤醒的情况下才会出现(即,您被唤醒,但实际上不应该被唤醒)。另外,处理InterruptedException通常是个坏主意,因为它不允许关闭线程(虚假唤醒与获取InterruptedException不同)
如果您知道只有一个服务员将继续,您可以使用notify而不是notifyAll。如果有大量等待的线程,这可能会更有效。但是,在使用notify时有一些需要特别小心的注意事项。服务员可能会收到通知并被打断,因此您对InterruptedException的处理需要重新通知(这样通知就不会丢失)。这意味着,即使你只想叫醒一名服务员,你也需要正确处理可能叫醒不止一名服务员的情况。通常,您必须确保您的代码正确地导致另一个线程继续运行,否则可能会导致死锁
当然。您可以有一个标志指示给定线程应继续,另一个标志指示所有线程应中止(系统关闭或算法中止)
我认为在现代,使用wait
和notify
是控制线程的非标准方式。可以说,如果没有边缘效应,java.util.concurrent
工具就无法完成任何事情。@OldCurmudgeon:我同意wait
和notify
是非标准的,因为java.util.concurrent
。但是是否有人在使用java.util.concurrent.locks.Condition
,它是wait/notify
的高级替代品?如果是这样,问题仍然存在。我认为将自己限制在条件下是无效的。生产者/消费者体系结构现在可以通过处理一对多、多对一和一对一数据流的各种BlockingQueue
类完美完成。除此之外,您还可以进入CyclicBarrier
、atomics甚至ForkJoinPool
来实现几乎任何目标。您还可以获得多种其他好处,如期货
和线程池
s。试图将旧的wait/notify
与j.u.concurrent
的丰富性进行比较是在比较粉笔和奶酪。确实,你对j.u.current
提供的设施有一点看法。