Java:等待布尔值变为真
我实现了一个任务,当前线程将等待以前的工作完成 代码: 另一个线程将Java:等待布尔值变为真,java,multithreading,Java,Multithreading,我实现了一个任务,当前线程将等待以前的工作完成 代码: 另一个线程将isPreviousWorkOne设置为true,然后我们可以运行doSomething()。但我认为我的代码不好: 我们检查每个100ms,它可能会占用一些CPU资源 很难添加等待超时。(如果ispreviousworkone永远不会成为真的会怎样?) 那么,如何正确地实现这样的等待呢?您试图实现的是监视器的工作。使用对象作为监视器,您可以在需要时让线程等待/唤醒 synchronized(lock) { while(
isPreviousWorkOne
设置为true,然后我们可以运行doSomething()
。但我认为我的代码不好:
100ms
,它可能会占用一些CPU资源ispreviousworkone
永远不会成为真的会怎样?)那么,如何正确地实现这样的等待呢?您试图实现的是监视器的工作。使用对象作为监视器,您可以在需要时让线程等待/唤醒
synchronized(lock)
{
while(!taskContext.isPreviousWorkDone())
{
try
{
// Object lock has to be accessible both by waiting thread and any
// other thread that marks the previous work as done
lock.wait();
}
}
}
现在,无论在哪里更新任务上下文,都必须唤醒等待的线程
// Method where you update taskContext
public synchronized void setWorkAsDone() throws Exception
{
// ...
_isPreviousWorkDone = true;
notifyAll();
// ...
}
改用倒计时闩锁。允许一个或多个线程等待某些操作完成 CountDownLatch是用给定的计数初始化的。需要等待某些条件/操作(使计数达到零)的线程调用wait()方法之一。通过调用countdown()方法,从完成某些操作的线程中递减计数。然后,所有等待的线程继续执行 示例
// create latch with count of one (1)
CountDownLatch latch = new CountDownLatch(1);
// create instances of classes that implement Runnable
Waiter waiter = new Waiter(latch);
Worker worker = new Worker(latch);
// start threads
new Thread(waiter).start();
new Thread(worker).start();
定义服务员可运行(等待某些操作完成)
定义工作线程可运行(执行某些操作)
避免
使用旧的wait-notifyjavaapi。原因是虚假唤醒。也就是说,您的线程在没有收到实际通知的情况下被唤醒,因此您必须检查您的条件是否满足,或者继续等待
来自的虚假唤醒
线程也可以在不被通知、中断或超时的情况下唤醒,即所谓的虚假唤醒。虽然这种情况在实践中很少发生,但应用程序必须通过测试本应导致线程被唤醒的条件来防范这种情况,并在条件不满足时继续等待。换句话说,等待应该总是在循环中发生,如下所示:
synchronized (obj) {
while (<condition does not hold>)
obj.wait(timeout);
... // Perform action appropriate to condition
}
synchronized(obj){
而()
对象等待(超时);
…//执行适合条件的操作
}
(有关此主题的更多信息,请参阅Doug Lea的“Java并发编程(第二版)”(Addison Wesley,2000)中的第3.2.3节,或Joshua Bloch的“有效Java编程语言指南”(Addison Wesley,2001)中的第50项。您可以构建超时检查此问题:使用等待而不是睡眠,并使用信号:)您可以使用
Object#wait
或ReentrantLock
和条件
countdownlock
或CyclicBarrier
,如果这种等待只发生一次。对于重复发生的内容,请使用ExecutorService
和Future
。
public class Waiter implements Runnable{
CountDownLatch latch = null;
public Waiter(CountDownLatch latch) {
this.latch = latch;
}
public void run() {
try {
// wait for the latch to be released
latch.await();
} catch (InterruptedException e) {
// set interupt flag
Thread.currentThread().interrupt();
// log interrupt
System.out.println("Interrupted");
}
System.out.println("Unblocked");
doSomething();
}
}
public class Worker implements Runnable {
CountDownLatch latch = null;
public Worker(CountDownLatch latch) {
this.latch = latch;
}
public void run() {
// do some job
// when ready release latch
latch.countDown();
System.out.println("Latch Released");
}
}
synchronized (obj) {
while (<condition does not hold>)
obj.wait(timeout);
... // Perform action appropriate to condition
}