我有以下课程:
public class Service{
private static final ExecutorService executor = Executors.newFixedThreadPool(4);
public synchronized void execute(Collection<Runnable> runs){
for(Runnable r: runs){
executor.execute(r);
}
}
public boolean isComplete(){
//should return true iff all tasks applied by the execute(Collection<Runnable> runs)
//method're finished their execution (normally or abruptly,
//it doesn matter)
}
}
如何实施isComplete()
方法。我需要检查当前是否有正在进行的任务。如果执行程序被清除(所有任务都已完成),则该方法应返回true,否则返回false。
答案 0 :(得分:4)
鉴于您使用的是ExecutorService
,您可以使用submit
代替execute
,并将返回的Future
存储在列表中。然后在isComplete()
内迭代所有Future
并在每个isDone()
上调用Future
。 (如果需要,此方法还允许您通过class Service{
private static final ExecutorService executor = Executors.newFixedThreadPool(4);
private List<Future<?>> futures;
public void execute(Collection<Runnable> runs){
futures = runs.stream()
.map(r -> executor.submit(r))
.collect(Collectors.toList());
}
public boolean isComplete(){
for (Future<?> future : futures)
if (!future.isDone()) return false;
return true;
}
}
)取消提交的任务。
例如†:
futures
根据您的使用情况,您可以通过从isComplete
列表中删除项目来获得更好的效果,但您(可能)需要同步 public synchronized boolean isComplete(){
Iterator<Future<?>> itr = futures.iterator();
while (itr.hasNext()) {
if (itr.next().isDone()) itr.remove();
else return false;
}
return true;
}
方法:
execute
† 在编写此代码示例时,它假定您只对Service
的每个实例调用synchronized
,因此不需要是execute
。如果您在每个Service
实例上有多个并发呼叫者futures
,请注意,这会在每次调用execute
时替换"test AND test2 OR test3 AND test4"
列表。您可以通过仅使用该类一次性或通过附加到期货来处理该问题。这完全取决于您的用例。
答案 1 :(得分:1)
您可以调用shutdown()
方法让执行程序终止所有线程并关闭池。然后调用isTerminated()
,如果所有线程都被终止,它将返回true。
如果要阻止执行,可以使用awaitTerminationMethod()
,最后shutDownNow()
将终止池,无论线程是否已完成执行。
答案 2 :(得分:1)
CountDownLatch解决了我的问题。
ExecutorService WORKER_THREAD_POOL
= Executors.newFixedThreadPool(10);
CountDownLatch latch = new CountDownLatch(2);
for (int i = 0; i < 2; i++) {
WORKER_THREAD_POOL.submit(() -> {
try {
// ...
latch.countDown();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
}
// wait for the latch to be decremented by the two remaining threads
latch.await();