user4129715 user4129715 - 1 month ago 5
Java Question

How to check if all tasks running on ExecutorService are completed

I'v got ConcurrentLinkedDeque which I'm using for synchronic push/pop elements,
and I'v got some async tasks which are taking one element from stack and if this element has neighbors It's pushing it to stack.

Example code:

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)
}
}
}
}


I would like to have additional statement in while loop which answers the question - "any task in Executor is working?"

Answer

There isn't a clean way to check if all Runnables are done if you use ExecutorService.execute(Runnable). Unless you build a mechanism to do so in the Runnable itself (which is sloppy in my opinion).

Instead:
Use ExecutorService.submit(Runnable). This method will return a Future<?> which is a handle to the result of a runnable. Using Futures provides a clean way to check results.

All you have to do is maintain a list of Futures that you submit, and then you can iterate over the whole list of Futures and either:
  A) wait for all the futures to be done in a blocking way or
  B) check if all the futures are done in a non-blocking way.

Here is a code example:

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
}
Comments