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?"
When using an Executor, we can shut it down by calling the shutdown() or shutdownNow() methods. Although, it won't wait until all threads stop executing. Waiting for existing threads to complete their execution can be achieved by using the awaitTermination() method.
The Java ExecutorService submit(Runnable) method also takes a Runnable implementation, but returns a Future object. This Future object can be used to check if the Runnable has finished executing.
This can be done by submitting a Callable task to an ExecutorService and getting the result via a Future object. The purpose of the Callable interface is similar to Runnable, but its method returns a value of type T. Integer value = result. get();
Using shutdownNow() The shutdownNow() is a hard signal to destroy ExecutorService immediately along with stopping the execution of all in-progress and queued tasks. Use this method, when we want the application to stop processing all tasks immediately.
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 }
Update: with Java 8+ CompletableFutures you can manage this with its new callback functions. First you will need to create all of the CompletableFutures you need which will also start running, eg:
We need to accumulate all the futures generated in an Array in order to pass them later to CompletableFuture.allOf(CompletableFutures...)
So let's say you have a list of people you want to calculate its days until birthday asynchronously:
First we create all those needed futures and collect them together in an array:
CompletableFuture<?>[] completables = people.stream() .map(p -> createCompletableFuture(p)) .toArray(CompletableFuture<?>[]::new); private CompletableFuture createCompletableFuture(Person p) { return CompletableFuture.runAsync(daysUntillBirthday(p)); }
Then you pass those completables to a new CompletableFuture:
CompletableFuture c = CompletableFuture.allOf(completables)
And you can now check if there are still futures running with:
c.isDone()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With