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

2022-09-03 16:00:47

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

while( !foo.isInitialized() ) {
     Thread.yield();
}

在主线程中。我知道有更强大的解决方案;尽管如此,加载器不是由我设计的,它基本上是一个只读库(我不能简单地,因为我不能让它给我发送一个;而且,它不会在完成后死亡),我只需要等到加载完成。wait()notify()

Java文档说(请注意,这在1.6文档中不存在,而是由1.7文档添加的)

很少适合使用此方法。

NetBeans 警告我

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

Google Codepro AnalytiX,OTOH说

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

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

注意:我想到了使用(Thread.sleep(0)和Thread.yield()语句是否等同?值得在这里提及);尽管如此,如果ing没有持续睡眠的“奖励”,为什么Java提供它 - 那么它的实际有效用例是什么?sleep()yield

稍微相关:有没有更好的解决方案来解决Thread.yield()? & Thread.Sleep或Thread.Yield。


答案 1

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

如果在生成时没有其他要计划的线程,则生成的线程可能会很快重新计划,从而导致 CPU 使用率过高。

除此之外,在这种情况下,我看不出它会比这更有害。但是,这是非常没有意义的 - 如果你要写一个忙等待循环,你可以做,避免给调度程序带来压力。while (!foo.isInitialized());

如果你不能有通知机制,你应该做的是至少在循环中睡觉。这将使您的CPU稍微休息一下。

这种循环的典型实现:

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

答案 2