Java cancel Future - How to wait for finish? - java

Long story short: I have a collection of Future objects. Some of them are already in progress, some are not. I iterate the collection and call future.cancel(false) which, according to the documentation, should cancel all Futures that are not currently running but should allow all the others to complete.
My question is: How do I know when a particular Future is completed after I have called future.cancel(false)? future.isDone() always returns true because cancel() was indeed called before that and future.get() always throws a CancellationException even though the Future is still running.
Any suggestions?

Since Future models the future result of a pending computation, and since that result is not forthcoming from a canceled future, it is reasonable that Future gives you no way to find out when the computation whose result has been disposed of will complete. In other words, you'd need another paradigm to achieve your goal with that approach.
If your wish is to wait for all the submitted tasks to complete, the closest thing which is directly supported by the Executor Service API is to shut down the entire executor service and wait for its termination.
If the above does not fit your solution, then I don't see a better approach than some custom solution, for example a custom implementation of Runnable, which does some housekeeping on the side so you can check when it has completed running.

You could add a flag to your Future implementation which will reflect the actual Future' state

given a Callable<Object> c:
futureTask1 = new FutureTask<Object>(c);
futureTask2 = new FutureTask<Void>(futureTask1, null);
executor.execute(futureTask2);
now if you want the result:
futureTask1.get()
if you're no longer interested in the result:
futureTask1.cancel(mayInterruptIfRunning)
if you want to wait to be sure the code in the callable is not (and will not become) running (whether never called, finished cancelling or finished producing the result):
futureTask2.get()
Even if cancelled before it started working, this waits for the executor to execute the scheduled task (which will to nothing if already cancelled), so this may unnecessariliy wait for other long-running tasks to complete. YMMV

Related

Queries on Java Future and RejectionHandler

I had some queries regarding Future usage. Please go through below example before addressing my queries.
http://javarevisited.blogspot.in/2015/01/how-to-use-future-and-futuretask-in-Java.html
The main purpose of using thread pools & Executors is to execute task asynchronously without blocking main thread. But once you use Future, it is blocking calling thread. Do we have to create separate new thread/thread pool to analyse the results of Callable tasks? OR is there any other good solution?
Since Future call is blocking the caller, is it worth to use this feature? If I want to analyse the result of a task, I can have synchronous call and check the result of the call without Future.
What is the best way to handle Rejected tasks with usage of RejectionHandler? If a task is rejected, is it good practice to submit the task to another Thread or ThreadPool Or submit the same task to current ThreadPoolExecutor again?
Please correct me if my thought process is wrong about this feature.
Your question is about performing an action when an asynchronous action has been done. Futures on the other hand are good if you have an unrelated activity which you can perform while the asynchronous action is running. Then you may regularly poll the action represented by the Future via isDone() and do something else if not or call the blocking get() if you have no more unrelated work for your current thread.
If you want to schedule an on-completion action without blocking the current thread, you may instead use CompletableFuture which offers such functionality.
CompletableFuture is the solution for queries 1 and 2 as suggested by #Holger
I want to update about RejectedExecutionHandler mechanism regarding query 3.
Java provides four types of Rejection Handler policies as per javadocs.
In the default ThreadPoolExecutor.AbortPolicy, the handler throws a runtime RejectedExecutionException upon rejection.
In ThreadPoolExecutor.CallerRunsPolicy, the thread that invokes execute itself runs the task. This provides a simple feedback control mechanism that will slow down the rate that new tasks are submitted.
In ThreadPoolExecutor.DiscardPolicy, a task that cannot be executed is simply dropped.
In ThreadPoolExecutor.DiscardOldestPolicy, if the executor is not shut down, the task at the head of the work queue is dropped, and then execution is retried (which can fail again, causing this to be repeated.)
CallerRunsPolicy: If you have more tasks in task queue, using this policy will degrade the performance. You have to be careful since reject tasks will be executed by main thread itself. If Running the rejected task is critical for your application and you have limited task queue, you can use this policy.
DiscardPolicy: If discarding a non-critical event does not bother you, then you can use this policy.
DiscardOldestPolicy: Discard the oldest job and try to resume the last one
If none of them suits your need, you can implement your own RejectionHandler.

Handle a lot of Futures given by asynchronous rest-requests

I wanna use the jersey-client for creating asynchronous rest-requests, the function delivers me Futures, so i can, in my understanding, invoke get, and if the request is finished it will return something.
So i am thinking, i could store the Futures in a map and look into them from time to time by one thread. Or maybe i should create a new thread everytime someone sending an asynchronous request. There is also a requirement that it shouldn't last forever (a timeout).
What do you think?
I often use a List<Future<Void>> to store the futures. As get() blocks, I just cycle through them rather than poll them.
There is also a requirement that it should last forever (a timeout).
I assume you mean its shouldn't last forever. This requires support in the library you are using to make the requests. If they can be interrupted you can cancel(true) the future either in your waiting thread or another ScheduledExecutorService. If they can't be interrupts you may have to stop() the thread but only as a last resort.
The javadoc says:
A Future represents the result of an asynchronous computation. Methods
are provided to check if the computation is complete, to wait for its
completion, and to retrieve the result of the computation. The result
can only be retrieved using method get when the computation has
completed, blocking if necessary until it is ready.
Therefore it is up to you to choose which strategy to adopt: it mostly depends on what you want to do with those requests.
You could place those Futures in any iterable structure before going through them. Block on each get may be a strategy if you can handle each result pretty fast and do need to check while waiting if other futures are already returned.

Should I call cancel(true) on Future<?> or my own FutureTask

I have a custom class MyFutureTask extends FutureTask<Void> upon which I do some code on the done() method.
I use an ExecutorService which I call submit(new MyFutureTask()) into it.
Now I can keep a reference to the Future<?> that gets returned after you call submit, but when I call cancel to that the isCancelled() method never returns true.
Should I ignore the Future<?> object that gets returned and instead work with MyFutureTask and call cancel(true) on that instead?
What is the use of the Future<?> object then?
edit: What's the difference between Future and FutureTask in Java? from this thread I understand the difference.
Besides the default cancel behavior I also want to attempt to stop a network call in progress so I guess the route I am going to use FutureTask is correct. Someone can confirm?
Don't use Executor.submit, instead use Executor.execute since you already have a Future. When you call submit, you are just needlessly wrapping your FutureTask in another FutureTask.
Also you can't "stop" a network trip. You have to wait until it returns or times out. What you do is call Future.cancel(true), then when your network trip returns look and see if the future has been canceled Future.isCancelled(). THen you can just stop doing what you were doing in the Future. For all intents and purposes it's the same effect as if you could cancel a network trip. To the end user (ie the client code or caller) it will appear the same way. The only side effect you might notice is if you have only a single thread executing tasks in which case the thread waiting on the network trip has to return before it will pick up the next task. If that's a problem using a pool of threads.
As an aside if you used NIO or some library thereof you could stop waiting on the result immediately, but that's a lot more work to code up.

How to wait for all tasks in an ThreadPoolExecutor to finish without shutting down the Executor?

I can't use shutdown() and awaitTermination() because it is possible new tasks will be added to the ThreadPoolExecutor while it is waiting.
So I'm looking for a way to wait until the ThreadPoolExecutor has emptied it's queue and finished all of it's tasks without stopping new tasks from being added before that point.
If it makes any difference, this is for Android.
Thanks
Update: Many weeks later after revisiting this, I discovered that a modified CountDownLatch worked better for me in this case. I'll keep the answer marked because it applies more to what I asked.
If you are interested in knowing when a certain task completes, or a certain batch of tasks, you may use ExecutorService.submit(Runnable). Invoking this method returns a Future object which may be placed into a Collection which your main thread will then iterate over calling Future.get() for each one. This will cause your main thread to halt execution until the ExecutorService has processed all of the Runnable tasks.
Collection<Future<?>> futures = new LinkedList<Future<?>>();
futures.add(executorService.submit(myRunnable));
for (Future<?> future:futures) {
future.get();
}
My Scenario is a web crawler to fetch some information from a web site then processing them. A ThreadPoolExecutor is used to speed up the process because many pages can be loaded in the time. So new tasks will be created in the existing task because the crawler will follow hyperlinks in each page. The problem is the same: the main thread do not know when all the tasks are completed and it can start to process the result. I use a simple way to determine this. It is not very elegant but works in my case:
while (executor.getTaskCount()!=executor.getCompletedTaskCount()){
System.err.println("count="+executor.getTaskCount()+","+executor.getCompletedTaskCount());
Thread.sleep(5000);
}
executor.shutdown();
executor.awaitTermination(60, TimeUnit.SECONDS);
Maybe you are looking for a CompletionService to manage batches of task, see also this answer.
(This is an attempt to reproduce Thilo's earlier, deleted answer with my own adjustments.)
I think you may need to clarify your question since there is an implicit infinite condition... at some point you have to decide to shut down your executor, and at that point it won't accept any more tasks. Your question seems to imply that you want to wait until you know that no further tasks will be submitted, which you can only know in your own application code.
The following answer will allow you to smoothly transition to a new TPE (for whatever reason), completing all the currently-submitted tasks, and not rejecting new tasks to the new TPE. It might answer your question. #Thilo's might also.
Assuming you have defined somewhere a visible TPE in use as such:
AtomicReference<ThreadPoolExecutor> publiclyAvailableTPE = ...;
You can then write the TPE swap routine as such. It could also be written using a synchronized method, but I think this is simpler:
void rotateTPE()
{
ThreadPoolExecutor newTPE = createNewTPE();
// atomic swap with publicly-visible TPE
ThreadPoolExecutor oldTPE = publiclyAvailableTPE.getAndSet(newTPE);
oldTPE.shutdown();
// and if you want this method to block awaiting completion of old tasks in
// the previously visible TPE
oldTPE.awaitTermination();
}
Alternatively, if you really no kidding want to kill the thread pool, then your submitter side will need to cope with rejected tasks at some point, and you could use null for the new TPE:
void killTPE()
{
ThreadPoolExecutor oldTPE = publiclyAvailableTPE.getAndSet(null);
oldTPE.shutdown();
// and if you want this method to block awaiting completion of old tasks in
// the previously visible TPE
oldTPE.awaitTermination();
}
Which could cause upstream problems, the caller would need to know what to do with a null.
You could also swap out with a dummy TPE that simply rejected every new execution, but that's equivalent to what happens if you call shutdown() on the TPE.
If you don't want to use shutdown, follow below approaches:
Iterate through all Future tasks from submit on ExecutorService and check the status with blocking call get() on Future object as suggested by Tim Bender
Use one of
Using invokeAll on ExecutorService
Using CountDownLatch
Using ForkJoinPool or newWorkStealingPool of Executors(since java 8)
invokeAll() on executor service also achieves the same purpose of CountDownLatch
Related SE question:
How to wait for a number of threads to complete?
You could call the waitTillDone() on Runner class:
Runner runner = Runner.runner(10);
runner.runIn(2, SECONDS, runnable);
runner.run(runnable); // each of this runnables could submit more tasks
runner.waitTillDone(); // blocks until all tasks are finished (or failed)
// and now reuse it
runner.runIn(500, MILLISECONDS, callable);
runner.waitTillDone();
runner.shutdown();
To use it add this gradle/maven dependency to your project: 'com.github.matejtymes:javafixes:1.0'
For more details look here: https://github.com/MatejTymes/JavaFixes or here: http://matejtymes.blogspot.com/2016/04/executor-that-notifies-you-when-task.html
Try using queue size and active tasks count as shown below
while (executor.getThreadPoolExecutor().getActiveCount() != 0 || !executor.getThreadPoolExecutor().getQueue().isEmpty()){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
}

JAVA - Cancel the ThreadPoolExecutor running tasks

What I need is a method similar to shutdownNow, but, be able to submit new tasks after that. My ThreadPoolExecutor will be accepting a random number of tasks during my program execution.
You can grab the Future of each submission, store that Future in a collection, then when you want to cancel the tasks, invoke future.cancel() of all queued tasks.
With this solution the Exectuor is still running and any running tasks are cancelled or will not run if they are queued.
Why not create your own ExecutorService that exhibits this behaviour?
Is it not enough to just do getQueue() and clear it? If you really need to attempt to stop running tasks, you would need to subclass the ThreadPoolExecutor and essentially re-implement shutdownNow() but only copy the bit that sends an interrupt to each thread. Mind you this still isn't any guarantee that you will actually cause them to immediately cease and do no further calculation. You'll need a totally different approach if you need to do that.

Categories

Resources