我有一个等待布尔值改变的线程:
while(!value)
{
Thread.sleep(1000)
}
// Do some work after change of the value
这不是我喜欢的方法,这是造成大量CPU消耗的原因。
有没有办法阻止线程,直到布尔值改变状态?
答案 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);
}