我刚刚遇到一些代码,这些代码使用wait-notify构造与其他成员方法中的类中定义的线程进行通信。 有趣的是,在获取锁之后,所有线程都在同步范围内进行定时 - 等待同一个锁(参见下面的代码片段)。稍后,在非同步范围内,线程执行其关键功能(即'//做一些有用的事情')。
我对这种机制的最佳猜测是,最小化线程的资源消耗,直到其他线程调用'someMethod'。专家们怎么想?如果是这种情况,有什么更好的方法来实现这种行为?
class SomeClass{
public void run() {
while (!isShuttingDown){
try {
synchronized (SomeClass.class) {
SomeClass.class.wait(500);
}
} catch (Throwable e) {
LOGGER.info(SomeClass.class.getSimpleName() + " reaper thread interrupted", e);
}
//do something useful1
}
}
public synchronized void someMethod(){
//do something useful2
synchronized (SomeClass.class) {
SomeClass.class.notifyAll();
}
//do something useful3
}
}
答案 0 :(得分:4)
如上所述here,
等待通知模式用于一组广泛的情况 线程需要告诉其他线程发生了一些事件。它是 常用于实现线程池或生产者 - 消费者 场景,特定线程或线程需要“拾取工作” 由其他线程创建(在这种情况下,已发生的“事件”) 是因为其中一个线程已经到了工作岗位。
答案 1 :(得分:1)
获取锁定后,所有线程在同步范围内进行定时 - 等待相同的锁定(请参阅下面的代码段)。
是的,模式很奇怪。通常我有一个类似的循环(虽然我总是使用private final lockObject
)等待一小段时间,因为我不希望方法旋转 - 过于频繁地执行它的任务。
我原以为另一种方法会锁定同一个变量,然后更新isShuttingDown
标志。但是执行其他// useful#
部分是一种奇怪的模式,因为有许多竞争条件会使代码无法确定有用部分的顺序。