Thread.yield()被认为有害吗?

vax*_*uis 14 java multithreading coding-style yield

在处理我的Java应用程序时,我有一个简单的多线程案例(一个异步资源加载器线程和一个主线程等待加载器完成,用进度更新UI),我想通过调用来解决

while( !foo.isInitialized() ) {
     Thread.yield();
}
Run Code Online (Sandbox Code Playgroud)

在主线程中.我知道有更强大的解决方案; 仍然,加载器不是由我设计的,它是一个基本上只读的库(我不能简单wait(),因为我无法让它发送给我notify();也就是说,它完成后不会死),我只需要等到加载完成.

Java doc说(注意这不存在于1.6文档中,并且是由1.7个文档添加的)

使用这种方法很少是合适的.

NetBeans警告我

方法yield()on的调用java.lang.Thread通常用于伪装同步问题,应该避免.

谷歌Codepro AnalytiX,OTOH说

Thread.yield()不应使用该方法,因为其行为在所有平台上都不一致.

我是否应该关注这些警告并尝试找到更好的解决方案(欢迎提出所有建议),还是应该将其视为"警告噪音"并抑制/忽略它们?

注意:我想到了使用sleep()(Is Thread.sleep(0)和Thread.yield()语句等效的明显可能性吗?值得一提); 仍然,如果yielding在持续睡眠中没有"奖励",为什么Java会提供它 - 那么它的实际有效用例是什么呢?

略有关联: Thread.yield()有更好的解决方案吗?&Thread.Sleep或Thread.Yield

K E*_*son 4

在没有任何等待机制的情况下调用 while 循环的主要问题Thread.yield()是,它很容易成为使用 100% 的核心之一的繁忙等待循环。

如果您让出时没有其他线程需要调度,则让出的线程可能会很快重新调度,从而导致 CPU 利用率较高。

除此之外,在这种情况下,我看不出它会比这更有害。然而,这是毫无意义的——如果您要编写一个忙等待循环,您可以这样做while (!foo.isInitialized());并避免给调度程序带来压力。

如果你没有通知机制,你应该做的是至少在循环中休眠。这将使您的 CPU 休息一下。

这种循环的典型实现:

while(!foo.isInitialized()) { 
    try {
        Thread.sleep(20);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        return; // or handle some other way
    }
}
Run Code Online (Sandbox Code Playgroud)