scu*_*gxl 6 java multithreading while-loop wait
我在"Thinking in java"中阅读了以下代码.
synchronized(obj)
{
while (condition_not_matched)
{
obj.wait();
}
//continue
dosomething();
}
Run Code Online (Sandbox Code Playgroud)
我的想法:
使用"if"是可以的,因为"等待"意味着它必须得到obj的锁定监视器,并且这里只能执行一个线程.
(1)为什么这里使用"while(condition)"而不是"if"?
(2)执行"obj.wait()"时发生了什么?currrent线程是否释放了"obj"的锁定?
(3)当另一个线程执行"obj.notify()"时,前一个线程发生了什么(它是否重新获取了obj的锁定?如果是,它必须是condition_not_matched,所以"如果"就足够了.)
我是错误?
使用if检查而不是在循环中反复检查是一个错误。使用循环有多种原因。
一种是“虚假唤醒”,这意味着wait方法可以在没有通知线程的情况下返回:基于退出wait方法的线程,推断必须已被通知是无效的。这可能不会发生很多,但是有可能需要处理。
但是主要原因是这一点:当线程等待时,它释放锁。当它收到通知时,它没有锁,必须再次获取它才能退出wait方法。仅仅因为线程被通知并不意味着它是下一个获得锁的线程。如果线程根据线程没有锁所有权时发生的事情来决定要做什么,那么在通知发生到线程发生之间,多个线程可能有机会对同一个共享对象执行操作。得到了锁,共享对象的状态可能不是线程认为的那样。使用while循环可以使线程在保持锁定的情况下检查它再次等待的条件,并在继续进行之前确认条件仍然有效。
小智 1
语句通过运行一次来if
检查表达式是真还是假,然后仅在表达式为真时才运行语句内的代码。
然而
条件继续执行while 语句中的代码,直到表达式为 true while
。此外,当您不知道可能需要循环条件多少次时,更适合使用 while 循环。
obj.wait()
- 导致当前线程等待,直到另一个线程调用该notify()
方法或nofityAll()
在这种情况下调用相应对象的方法。如果超时作为参数传递,则执行将等待,直到经过一定的时间。
obj.notify()
将唤醒正在相应对象监视器上等待的单个线程。仅当当前线程放弃对象上的锁后,唤醒的线程才会继续执行。