我对wait / notify的优点有一些误解。据我所知,处理器核心在两种情况下都没有任何帮助,所以什么原因是tro写复杂的等待/通知块代码而不是仅仅在循环中等待? 我清楚的是,如果只在一个核心上执行两个线程,则wait / notify不会窃取处理器时间。
答案 0 :(得分:2)
“在一个周期中等待”通常被称为“忙碌循环”或“忙碌等待”:
while ( ! condition()) {
// do nothing
}
workThatDependsOnConditionBeingTrue();
这是非常不尊重可能需要CPU时间的其他线程或进程(如果可以的话,它需要100%的时间来自该核心)。所以还有另一种变体:
while ( ! condition()) {
sleepForShortInterval();
// do nothing
}
workThatDependsOnConditionBeingTrue();
这种变体中的小睡眠将大大降低CPU使用率,即使它长约100ms,除非您的应用程序是实时的,否则这种情况不应太明显。
请注意,条件实际变为true和sleepForShortInterval()
结束之间通常会有延迟。如果,为了对他人更礼貌,你睡得更久 - 延迟会增加。这在实时场景中通常是不可接受的。
执行此操作的好方法,假设正在检查的任何condition()
正在从另一个线程更改,是让另一个线程在完成您正在等待的任何内容时唤醒您。更清洁的代码,没有浪费CPU,也没有延迟。
当然,实现忙碌等待的速度更快,并且可以为快速的情况辩护。
请注意,在多线程场景中,condition()
可以更改为false和true,您需要在while
和workThatDependsOnConditionBeingTrue()
之间保护您的代码以避免其他线程在这个精确的时间点改变它的值(这被称为种族编码,并且在事后很难调试。)
答案 1 :(得分:1)
我认为您几乎通过说
来回答您的问题我很清楚wait / notify不会窃取处理器时间以防万一。
我唯一想补充的是,无论是核心还是多核,都是如此。与wait/notify
循环或定期检查相比,while
不会使cpu处于忙碌等待状态。
不运行核心但等待的原因是什么?在任何情况下都没有任何有用的工作,并且当它处于等待状态时你无法使用核心。
我认为您从单个应用程序的角度来看它,其中只有一个应用程序正在运行一个线程。从现实世界的应用程序(例如web / app服务器或独立)中可以看出,many threads
正在运行competing for cpu cycles
- see the advantage of wait/notify.
- 你可以while busy-wait
你绝对不会想要一个单独的线程只是做一个忙碌的等待并烧掉cpu周期。
即使在系统上运行单个应用程序/线程,也总会有OS进程运行,并且其相关进程会持续竞争CPU周期。您不希望他们饿死他们,因为应用程序正在执行document = {'pattern_key' : {}}
。
引自戈登的评论
等待循环,因为你建议你不断检查你正在等待的东西是否已经完成,这是浪费,如果你使用睡眠你只是猜测时间,而等待/通知你闲置,直到过程你在等着告诉你它已经完成了。
答案 2 :(得分:1)
通常,您的应用程序不是CPU上运行的唯一应用程序。首先,使用非旋转等待是对竞争CPU的其他进程/线程的礼貌行为,以便做一些有用的工作。如果你的线程要做一些有用的事情或只是旋转一个错误的标志,CPU调度程序就不能知道先验。所以,它不能基于此调整自己,除非你告诉它你不想运行,因为你没有什么可做的。
确实,忙等待比让线程进入睡眠更快,这就是为什么通常以混合方式实现wait()方法的原因。它首先旋转一段时间,然后它实际上进入睡眠状态。
此外,它不只是在循环中等待。您仍然需要同步访问您正在旋转的资源。否则,你将成为竞争条件的受害者。
如果您觉得需要更简单的界面,也可以考虑使用CyclicBarrier
,CountDownLatch
或SynchronousQueue
。