"wait()"和"sleep()"在Java中的区别
"wait()"和"sleep()"在Java中的区别
线程中的wait()
和sleep()
有何区别?
我理解wait()
的线程仍处于运行模式并使用CPU周期,而sleep()
则不会消耗任何CPU周期,这个理解正确吗?
为什么我们需要同时使用wait()
和sleep()
?
它们在低级别的实现中有何不同?
admin 更改状态以发布 2023年5月21日
一个wait
可以被另一个线程通过在等待的监视器上调用notify
而"唤醒",而sleep
则不能。另外,wait
(和notify
)必须发生在一个synchronized
块上的监视器对象上,而sleep
则不需要:
Object mon = ...; synchronized (mon) { mon.wait(); }
此时正在执行的线程等待并释放监视器,另一个线程可以对相同的mon
对象执行notify
,第一个线程(假设它是唯一在监视器上等待的线程)将被唤醒。
synchronized (mon) { mon.notify(); }
如果有多个线程在等待监视器,您还可以调用notifyAll
来唤醒全部线程。但是,只有一个线程能够获取监视器(请记住,在synchronized
块中执行wait
),其他线程将被阻塞直到它们可以获得监视器的锁。
另一个要点是,您在Object
本身上调用wait
(即,在对象的监视器上等待),而在Thread
上调用sleep
。
另一个问题是可能会出现 wait 的虚假唤醒(即等待的线程在没有明显原因的情况下被唤醒)。应该像下面这样,在某个条件上忙等待(spin)的同时总是使用 wait
:
synchronized { while (!condition) { mon.wait(); } }