等到布尔值改变状态

时间:2013-09-26 10:11:06

标签: java multithreading boolean

我有一个等待布尔值改变的线程:

while(!value)
{
  Thread.sleep(1000)
}
// Do some work after change of the value

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

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

6 个答案:

答案 0 :(得分:69)

  

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

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

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

private volatile boolean value;

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

答案 1 :(得分:44)

您需要一种避免忙碌等待的机制。旧的wait/notify机制充满了陷阱,所以更喜欢java.util.concurrent库中的某些内容,例如CountDownLatch

public final CountDownLatch latch = new CountDownLatch(1);

public void run () {
  latch.await();
  ...
}

在另一边打电话

yourRunnableObj.latch.countDown();

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

答案 2 :(得分: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();
   }
}

答案 3 :(得分:2)

好吧也许这个可以解决你的问题。请注意,每次进行更改时,都要调用release()方法来释放等待。

Integer any = new Integer(0);

public synchronized boolean waitTillChange() {
    any.wait();
    return true;
}

public synchronized void change() {
    any.notify();
}

答案 4 :(得分:1)

在这种情况下我更喜欢使用互斥机制,但是如果你真的想使用boolean,那么你应该将它声明为volatile(以提供跨线程的变化可见性)并且只需使用该boolean运行无体循环条件:

//.....some class

volatile boolean someBoolean; 

Thread someThread = new Thread() {

    @Override 
    public void run() {
        //some actions
        while (!someBoolean); //wait for condition 
        //some actions 
    }

};

答案 5 :(得分:0)

public Boolean test() throws InterruptedException {
    BlockingQueue<Boolean> booleanHolder = new LinkedBlockingQueue<>();
    new Thread(() -> {
        try {
            TimeUnit.SECONDS.sleep(2);
            booleanHolder.put(true);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }).start();
    return booleanHolder.poll(4, TimeUnit.SECONDS);
}