等到布尔值改变状态

Mar*_*öll 44 java multithreading boolean

我有一个等待布尔值改变的线程,如下所示:

while(!value)
{
  Thread.sleep(1000)
}
// Do some work after change of the value
Run Code Online (Sandbox Code Playgroud)

这不是我喜欢的方法,这是造成大量CPU消耗的原因.

有没有办法阻止线程,直到布尔值改变状态?

Mic*_*rdt 79

这不是我喜欢的方法,这是造成大量CPU消耗的原因.

如果这实际上是你的工作代码,那就保持这样吧.每秒检查一次布尔值会导致无法测量的CPU负载.没有任何.

真正的问题是,检查该值的线程可能看不到由于缓存而在任意长时间内发生的更改.要确保值始终在线程之间同步,您需要将volatile关键字放在变量定义中,即

private volatile boolean value;
Run Code Online (Sandbox Code Playgroud)

请注意,将访问放在synchronized块中(例如,在使用其他答案中描述的基于通知的解决方案时)将具有相同的效果.


Mar*_*nik 46

你需要一种避免忙碌等待的机制.旧的wait/notify机制充满了陷阱,所以更喜欢java.util.concurrent图书馆的东西,例如CountDownLatch:

public final CountDownLatch latch = new CountDownLatch(1);

public void run () {
  latch.await();
  ...
}
Run Code Online (Sandbox Code Playgroud)

并在另一边打电话

yourRunnableObj.latch.countDown();
Run Code Online (Sandbox Code Playgroud)

但是,启动一个线程除了等待它之前什么都不做,仍然不是最好的方法.您还ExecutorService可以将您提交的任务作为任务提交给满足条件时必须完成的工作.

  • 我可以推荐`Java.util.concurrent.BlockingQueue` 及其各种实现吗?`take()` 和 `offer()` 方法是同步的一个很好的起点。 (2认同)

Sub*_*der 7

怎么样 wait-notify

private Boolean bool = true;
private final Object lock = new Object();

private Boolean getChange(){
  synchronized(lock){
    while (bool) {
      bool.wait();
    }
   }
  return bool;
}
public void setChange(){
   synchronized(lock){
       bool = false;
       bool.notify();
   }
}
Run Code Online (Sandbox Code Playgroud)

  • `bool`是一个可变字段,你不能同步它. (8认同)
  • 您需要等待锁定,而不是 bool - 但在这种情况下使用简单的 CountDownLatch 似乎是更好的解决方案。 (3认同)
  • 现在您正在一个非最终字段上进行同步。在 `setChange` 中,您将首先修改它,然后通知新的 `false` 实例。结果:等待更早的 `true` 实例的线程永远不会得到通知。另一个很好的例子说明为什么要*避免*整个机制。 (2认同)