【问题标题】:Efficiency - use of Thread.yield in loop that waits for variable change效率 - 在等待变量更改的循环中使用 Thread.yield
【发布时间】:2013-04-25 06:10:52
【问题描述】:

我有一些如下所示的代码:

while (this.conditionIsNotYetMet){
    if (timeout()) break;
    // Don't do anything, just wait till the condition is 
    // filled by a different thread or timeout occurs.
}
performSomeCode(); // this code relies on the condition having been met

代码有效 - 最终另一个线程满足条件,代码执行。

我很好奇加入 Thread.yield() 是否是一个好主意 - 无论哪种方式似乎都是正确的,在这个阶段我感觉不到性能差异 - 但是我担心将来它可能会有所作为,例如在不同的平台上。

即代码会变成

while (this.conditionIsNotYetMet){
    if (timeout()) break;
    Thread.yield(); // <----  CHANGE IS HERE!!!!
    // Don't do anything, just wait till the condition is 
    // filled by a different thread or timeout occurs.
}
performSomeCode(); // this code relies on the condition having been met

我知道可能有一种更正式的方法可以使用锁或 AsynchronousTasks 来实现这种模式,但是这个解决方案目前运行良好并且足够清晰,那么为什么要改变呢?

【问题讨论】:

  • 你可以实现wait-notify模式
  • timeout() 是做什么的?
  • 我在这里使用 timeout() 来表示任何类型的超时条件以确保活力。在我的例子中,它检查 System.currentTimeMillis() 与 while 循环之前进行的测量

标签: java multithreading asynchronous


【解决方案1】:

不,您几乎不应该使用yield(),绝对不应该等待条件变为真。相反,您应该研究一个“真正的”并发控制机制,例如Condition(导致线程休眠直到被另一个线程唤醒)或CountDownLatch(导致线程休眠直到发生一定数量的信号)。

【讨论】:

    【解决方案2】:

    yield() 在您看到其他线程停滞的情况下很有用。换句话说,你有一个非常活跃的线程,它总是以某种方式优先于其他从未真正做任何事情的线程。从您的活动线程调用 yield() 会强制它向另一个正在运行的线程提供更改。

    如果你的程序和你的例子一样简单,你可能不需要调用 yield,另外取决于 timeout() 是如何实现的(如果它有一个 Thread.sleep()Object.wait() 在里面)它也会隐式地产生就像 yield 一样的上下文切换。

    因此,您不需要编写它,但无论如何您可能已经获得了它的效果。

    PS:正如 Extreme Coders 所指出的,您可能想要使用等待通知模式,这里是 an example

    【讨论】:

    • 如果你反复调用 yield() ,99% 以上的时间它什么都不做。
    • 好的,我看过你链接的例子......我对如何在我的情况下使用锁(而不是条件)有点困惑。我在这里没有要保护的共享资源,我只是希望一个线程在继续之前等待一个条件(由另一个线程引起)发生。我应该在哪里调用 lock.lock()?
    • 抱歉让您感到困惑,我实际上是在将您指向 Jared Russel 答案中的第一个代码 sn-p。那个不使用锁,而是等待/通知
    【解决方案3】:

    调用 yield() 只是对操作系统的一个提示,除非有线程在等待,否则它可能什么都不做。如果你想让 CPU 休息一下,你可以调用 Thread.sleep(10); 10 毫秒,如果你愿意,可以更短。

    顺便说一句,鉴于您正在等待超时,您可以调用

    Thread.sleep(timeUntilTimeoutInMilliSeconds);
    

    【讨论】:

    • 我想我并不真正关心咀嚼 CPU,只是我不希望我的 while 循环减慢其他线程的速度......所以听起来你说产量是适合这个吗?
    • 如果你没有空闲的CPU是合适的,如果你有空闲的CPU,它不会有任何区别(或伤害)
    • 好吧,紧循环可能仍然会伤害您的其他线程,因为 CPU 会变得更热,然后 CPU 的频率会在所有线程中降低。 (间接地,它可能会导致少量的冰川融化);-)
    猜你喜欢
    • 1970-01-01
    • 2013-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-21
    • 1970-01-01
    • 2022-07-15
    • 1970-01-01
    相关资源
    最近更新 更多