我正在尝试安排等待某种情况发生的线程。如果condition为true,则返回一些结果,否则再安排自己在一段延迟后执行。为实现此目的,我使用Executors
来安排Callable<Boolean>
,但在第二次重新安排后它会挂起。
final ExecutorService executor = Executors.newFixedThreadPool(2);
final MutableBoolean status = new MutableBoolean(false);
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Waiting now to set status");
try {
Thread.sleep(5*1000);
System.out.println("status is now true");
status.setValue(true);
} catch (InterruptedException e) {
}
}
}).start();
Future<Boolean> future = executor.submit(new Callable<Boolean>() {
public int count=0;
@Override
public Boolean call() throws Exception {
if(status.isTrue()){
System.out.println("Condition has become true now");
return status.booleanValue();
} else {
System.out.println("Not true yet, count" + count++ + " Rescheduling");
Future<Boolean> future = executor.submit(this);
return future.get();
}
}
});
boolean finalStatus = future.get();
System.out.println("Final status" + finalStatus);
输出:
Waiting now to set status
Not true yet, count0 Rescheduling
Not true yet, count1 Rescheduling
status is now true
有关可能出现的问题的任何建议?
由于
答案 0 :(得分:1)
您创建了一个大小为2的线程池。然后,您从池中运行的作业(递归地)向该池提交任务,并等待它们完成(调用future.get())。
答案 1 :(得分:1)
使用executor.submit(this)
每次都会向线程池提交一个新任务,线程池不会(也不应该)检查线程池中的线程是否已经执行了相同的任务。由于线程池只有两个线程,因此两个线程都将非常快速地使用并无限期地等待。
脏修复如下:
@Override
public Boolean call() throws Exception {
while (true) {
if(status.get()){
System.out.println("Condition has become true now");
return status.get();
}
}
}
但这会导致非常高的CPU使用率。正如Brett Okken建议的那样,使用预定的执行服务。或者,如果状态在不久的将来应始终更改为true
,请使用CountDownLatch等等屏障立即对状态更改做出反应。