3 回答
TA贡献1880条经验 获得超4个赞
这样的轮询绝对是最不受欢迎的解决方案。
我假设您有另一个线程将做一些事情来使条件成立。有几种同步线程的方法。在您的情况下,最简单的方法是通过对象发出通知:
主线程:
synchronized(syncObject) {
try {
// Calling wait() will block this thread until another thread
// calls notify() on the object.
syncObject.wait();
} catch (InterruptedException e) {
// Happens if someone interrupts your thread.
}
}
其他线程:
// Do something
// If the condition is true, do the following:
synchronized(syncObject) {
syncObject.notify();
}
syncObject本身可以很简单Object。
TA贡献1772条经验 获得超8个赞
EboMike的答案和Toby的答案都在正确的轨道上,但是它们都有致命的缺陷。该缺陷称为丢失通知。
问题是,如果一个线程调用foo.notify(),它将根本不做任何事情,除非某个其他线程已经在foo.wait()调用中处于休眠状态。对象,foo不记得它已收到通知。
有一个原因导致不允许您调用,foo.wait()或者foo.notify()除非线程在foo上同步。这是因为避免丢失通知的唯一方法是使用互斥量保护条件。完成后,它看起来像这样:
使用者线程:
try {
synchronized(foo) {
while(! conditionIsTrue()) {
foo.wait();
}
doSomethingThatRequiresConditionToBeTrue();
}
} catch (InterruptedException e) {
handleInterruption();
}
生产者线程:
synchronized(foo) {
doSomethingThatMakesConditionTrue();
foo.notify();
}
更改条件的代码和检查条件的代码都在同一对象上同步,并且使用者线程在等待之前显式测试条件。wait()当条件为真时,用户无法错过通知并永远陷入通话中。
另请注意,这wait()是一个循环。这是因为,在一般情况下,当使用者重新获取foo锁并唤醒时,其他一些线程可能再次使条件变为假。即使您的程序无法做到这一点,在某些操作系统中,foo.wait()即使foo.notify()没有被调用,也可能返回。这被称为“ 伪唤醒”,它被允许发生,因为它使等待/通知在某些操作系统上更容易实现。
添加回答
举报