我有ConcurrentLinkedDeque,用于同步推送/弹出元素,
我有一些异步任务,它们从堆栈中取出一个元素,并且如果该元素有邻居,则会将其插入堆栈。

示例代码:

private ConcurrentLinkedDeque<Item> stack = new ConcurrentLinkedDeque<>();
private ExecutorService exec = Executors.newFixedThreadPool(5);

    while ((item = stack.pollFirst()) != null) {
                if (item == null) {
                } else {
                    Runnable worker = new Solider(this, item);
                    exec.execute(worker);
                }
            }

   class Solider{
         public void run(){
             if(item.hasNeighbors){
                for(Item item:item.neighbors){
                    stack.push(item)
                }
             }
         }
    }

我想在while循环中有另外一条语句来回答问题-“执行程序中的任何任务都在工作?”

最佳答案

如果使用ExecutorService.execute(Runnable),没有一种干净的方法可以检查所有Runnable是否都已完成。除非您在Runnable本身中构建了一种机制来这样做(在我看来这是草率的)。

相反:
使用ExecutorService.submit(Runnable)。此方法将返回Future<?>,它是Runnable结果的句柄。使用 future 提供了一种检查结果的干净方法。

您要做的只是维护您提交的 future 列表,然后可以遍历整个 future 列表,并且可以:
A)等待所有 future 以封闭方式完成,或
B)检查所有 future 是否以非阻塞方式完成。

这是一个代码示例:

List<Future<?>> futures = new ArrayList<Future<?>>();
ExecutorService exec = Executors.newFixedThreadPool(5);

// Instead of using exec.execute() use exec.submit()
// because it returns a monitorable future
while((item = stack.pollFirst()) != null){
    Runnable worker = new Solider(this, item);
    Future<?> f = exec.submit(worker);
    futures.add(f);
}

// A) Await all runnables to be done (blocking)
for(Future<?> future : futures)
    future.get(); // get will block until the future is done

// B) Check if all runnables are done (non-blocking)
boolean allDone = true;
for(Future<?> future : futures){
    allDone &= future.isDone(); // check if future is done
}

10-05 18:59
查看更多