How to interrupt ExecutorService's threads - java

When using the ExecutorService returned by Executors.newSingleThreadExecutor(), how do I interrupt it?

In order to do this, you need to submit() a task to an ExecutorService, rather than calling execute(). When you do this, a Future is returned that can be used to manipulate the scheduled task. In particular, you can call cancel(true) on the associated Future to interrupt a task that is currently executing (or skip execution altogether if the task hasn't started running yet).
By the way, the object returned by Executors.newSingleThreadExecutor() is actually an ExecutorService.

Another way to interrupt the executor's internally managed thread(s) is to call the shutdownNow(..) method on your ExecutorService. Note, however, that as opposed to #erickson's solution, this will result in the whole ThreadPoolExecutor becoming unfit for further use.
I find this approach particularly useful in cases where the ExecutorService is no longer needed and keeping tabs on the Future instances is otherwise unnecessary (a prime example of this being the exit(..) method of your application).
Relevant information from the ExecutorService#shutdownNow(..) javadocs:
Attempts to stop all actively executing tasks, halts the processing of
waiting tasks, and returns a list of the tasks that were awaiting
execution.
There are no guarantees beyond best-effort attempts to stop processing
actively executing tasks. For example, typical implementations will
cancel via Thread.interrupt, so any task that fails to respond to
interrupts may never terminate.

One proper way could be customizing/injecting the ThreadFactory for the ExecutorService and from within the thread factory, you got the handle of the thread created, then you can schedule some task to interrupt the thread being interested.
Demo code part for the overwrited method newThread in ThreadFactory:
ThreadFactory customThreadfactory new ThreadFactory() {
public Thread newThread(Runnable runnable) {
final Thread thread = new Thread(runnable);
if (namePrefix != null) {
thread.setName(namePrefix + "-" + count.getAndIncrement());
}
if (daemon != null) {
thread.setDaemon(daemon);
}
if (priority != null) {
thread.setPriority(priority);
}
scheduledExecutorService.schedule(new Callable<String>() {
public String call() throws Exception {
System.out.println("Executed!");
thread.interrupt();
return "Called!";
}
}, 5, TimeUnit.SECONDS);
return thread;
}
}
Then you can use below code to construct your ExecutorService instance:
ExecutorService executorService = Executors.newFixedThreadPool(3,
customThreadfactory);
Then after 5 seconds, an interrupt signal will be sent to the threads in ExecutorService.

Related

Task Execution and wait for tasks to finish: Java

There is a generic queue of tasks where new tasks get added. I want to write code that will create more work in terms of tasks by adding them to the queue. The task that added the work to the queue will wait for all tasks to complete by polling the queue.
What would be the best way to implement it using Java. I was thinking of something on the lines of Simple threads by implementing a runnable interface and make it run in an infinite loop and sleep in between, wake up to see if there is any progress. If the progress is happening, keep on looping, if it has completed break out of the loop. Is there any other good and performance efficient way to implement this ?
How the tasks complete?
The tasks are submitted to a Queue. The Queue is polled by an executor and it runs the tasks.
What i want to do?
Poll that queue to see if the task has completed or is still executing.
What you're describing here, may be a rough sketch of a work queue. You could enqueue processes for asynchronous processing, wait for a notification of completion, and then terminate. This works, but there are new concurrency tools available. I recommend reading the Java Concurrency Lesson.
The new model for concurrency allows you to separate the concurrency concerns from the thread via tasks, Runnable and Callable and the ExecutorService. Rather than working directly with threads and building your own thread pool try to let the Executor do the heavy lifting for you.
...
ExecutorService ex = Executors.newSingleThreadExecutor();
....
You may hand tasks, in the form of Runnables and Callables, to the ExecutorService and receive in return Future objects which may be used to monitor the task's progress.
Future<String> f = executor.submit(new Foo());
....
class Foo implements Callable<String> {
#Override
public String call() throws Exception {
return "Bar";
}
}
You may use an ExecutorCompletionService to monitor the completion of tasks for you :
CompletionService<String> cs = new ExecutorCompletionService<String>(executor);
Future<String> f = cs.submit(new Foo());
... // Let's say you've added TASK_COUNT tasks
for (int i = 0; i < TASK_COUNT ; i++ ) {
try {
String str = cs.take().get();
if (str != null) {
System.out.println(str); //Handle the result of the Callable
continue;
}
} catch (ExecutionException ignore) {}
}
now you've received a result per callable, you can clean up your tasks using the Future f object you received earlier with cs.submit(new Foo()) , by invoking
f.cancel(true)
on each task. And finally, don't forget to clean up your executor with
executor.shutdown();
There is a lot more to concurrency than this, but I believe that the above illustrates a means to meet your needs. I'd recommend reading the JavaDoc as well.
Use java.util.concurrent.Future and a java.util.concurrent.CompletionService.
You can use Fork/Join framework from java 7

Why set the interrupt bit in a Callable

So, this resource (http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html) suggest to set the interrupt bit in a Thread when that Thread does not deal with the interrupt itself, "so that code higher up on the call stack can learn of the interruption and respond to it if it wants to."
Let's say I'm using an ExecutorService to run something in a different Thread. I construct a Callable and pass this Callable into ExecutorService.submit(), which returns a Future. If the Callable gets interrupted and then resets the interrupt bit, the associated Future will not throw an InterruptedException when Future.get() is called. So what would be the purpose of setting the interrupted bit in the Callable if this Future is the only way the main Thread has access to the spawned Thread.
class MyCallable implements Callable<String> {
#Override
public String call() {
while (!Thread.currentThread().isInterrupted()) {
}
Thread.currentThread().interrupt();
return "blah";
}
}
ExecutorService pool = makeService();
Future<String> future = pool.submit(new MyCallable());
// Callable gets interrupted and the Callable resets the interrupt bit.
future.get(); // Does not thrown an InterruptedException, so how will I ever know that the Callable was interrupted?
You are correct that the interrupt flag is not passed between the 2 threads in this scenario (that's how the built in ExecutorService was designed for whatever reason). If you want the main thread to see the interrupted status of the callable, then you must throw InterruptedException from your call method.
class MyCallable implements Callable<String> {
#Override
public String call() {
// ...
if(Thread.currentThread().isInterrupted()) {
throw new InterruptedException();
}
return "blah";
}
}
Note, you still won't get InterruptedException directly from Future.get() in this scenario. since it was thrown by the callable, it will be wrapped in an ExecutionException (this is so you can distinguish between an interruption of the callable and an interruption of the main thread).
Interrupting a thread is supposed to terminate it, but in a less fragile way than kill(). The interrupted state of the thread is checked only during various blocking operations.
If your thread has been interrupted during one of these operations, an InterruptedException is thrown. When this happens, you want to exit cleanly, as quickly as you can. So, what should a Callable do if the executor service thread is interrupted?
If its action is short, one valid option is to just complete that action normally, but set the interrupted state on the thread so that the executor service will shut down after this action completes.
If the action is longer, you may want to instead throw an exception telling the caller that the action was interrupted.

Return to main thread as soon as one child thread throws an exception

I'm using Executors.newCachedThreadPool() and invokeAll with a List of Callables to do long-running multithreaded processing.
My main thread is blocked until all threads did finish and I can process the Futures returned by invokeAll. I'd like however invokeAll to immediately return if one of the Callables throw an exception and terminate the other threads.
Using execute instead of invokeAll would block on the first future.get() which needs not to be the one that throws the execption.
Using busy waiting to loop through all the futures and checking isDone() seems not to be the best way either.
You can use more complex synchronization mechanisms like latches, barriers or semaphores, but have a look at ExecutorCompletionService. It's a lightweight wrapper around ExecutorService that allows you to listen for the first finished task. Here is a quick example:
final ExecutorService executorService = Executors.newCachedThreadPool();
final ExecutorCompletionService<String> completionService =
new ExecutorCompletionService<String>(executorService);
for (int i = 0; i < 10; ++i) {
completionService.submit(new Task());
}
completionService.take().get();
The code is pretty simple. First you wrap executorService with completionService. Later you use it to submit tasks one after another. The last line is crucial. It takes the first task that finished and tries to retrieve the result. If it thrown an exception, it will be rethrown here, wrapped with ExecutionException:
try {
completionService.take().get();
} catch (ExecutionException e) {
e.getCause(); //this was thrown from task!
}
Inside catch block you can somehow handle the exception, e.g. canceling remaining tasks or shutting down the whole thread pool.
Of course you are free to wait for all tasks to finish by calling take() ten times. Each call will block as long as there is at least one task finished.

Java producer/consumer, detecting end of processing

I'm preparing an application where a single producer generates several million tasks, which will then be processed by a configurable number of consumers. Communication from producer to consumer is (probably) going to be queue-based.
From the thread that runs the producer/generates the tasks, what method can I use to wait for completion of all tasks? I'd rather not resume to any periodic polling to see if my tasks queue is empty. In any case, the task queue being empty isn't actually a guarantee that the last tasks have completed. Those tasks can be relatively long-running, so it's quite possible that the queue is empty while the consumer threads are still happily processing.
Rgds, Maarten
You might want to have a look at the java.util.concurrent package.
ExecutorService
Executors
Future
The executor framework already provides means to execute tasks via threadpool. The Future abstraction allows to wait for the completition of tasks.
Putting both together allows you coordinate the executions easily, decoupling tasks, activities (threads) and results.
Example:
ExecutorService executorService = Executors.newFixedThreadPool(16);
List<Callable<Void>> tasks = null;
//TODO: fill tasks;
//dispatch
List<Future<Void>> results = executorService.invokeAll(tasks);
//Wait until all tasks have completed
for(Future<Void> result: results){
result.get();
}
Edit: Alternative Version using CountDownLatch
ExecutorService executorService = Executors.newFixedThreadPool(16);
final CountDownLatch latch;
List<Callable<Void>> tasks = null;
//TODO: fill tasks;
latch = new CountDownLatch(tasks.size());
//dispatch
executorService.invokeAll(tasks);
//Wait until all tasks have completed
latch.await();
And inside your tasks:
Callable<Void> task = new Callable<Void>()
{
#Override
public Void call() throws Exception
{
// TODO: do your stuff
latch.countDown(); //<---- important part
return null;
}
};
You want to know where every tasks completes. I would have another queue of completed task reports. (One object/message per task) When this count reaches the number of tasks you created, they have all completed. This task report can also have any errors and timing information for the task.
You could have each consumer check to see if the queue is empty when they dequeue, and, if it is, pulse a condvar (or a Monitor, since I believe that's what Java has) on which the main thread is waiting.
Having the threads check a global boolean variable (marked as volatile) is a way to let the threads know that they should stop.
You can use join() method for each thread ..so that till all the threads are done your main thread will not end! And by this way you can actually find out whether all the threads are done or not!

Time limit on individual threads with ExecutorService

I have an ExecutorService managing a number of Callables. The tasks that the Callables run are mostly black box transformations and number crunching. Under certain conditions, the data being transformed will oscillate and the thread will take over an hour to finish. For comparison, most threads are completed within a minute.
It's been deteremined that the data from the long-running threads is not relevent. I would like to interrupt any thread that runs longer than a certain amount of time. What would the best way to do this?
Use a ScheduleExecutorService to schedule a task to taskFuture.cancel(true) the long running task when the timeout is reached. If the task finishes before then it won't be cancelled.
ExecutorService service = Executors.newFixedThreadPool(N);
ScheduledExecutorService canceller = Executors.newSingleThreadScheduledExecutor();
public <T> Future<T> executeTask(Callable<T> c, long timeoutMS){
final Future<T> future = service.submit(c);
canceller.schedule(new Callable<Void>(){
public Void call(){
future.cancel(true);
return null;
}
}, timeoutMS, TimeUnit.MILLI_SECONDS);
return future;
}
You could cancel the future etc as in the other answers, but you need to make sure that your threads which are "number crunching" can handle the interrupt and terminate gracefully. You say that this a black box operation - how certain are you that the interrupted status of the thread is being checked actively within the black box? If it isn't, you can't cancel it with an interrupt. The black box needs to be written with interruption in mind.
The best way for you to do this would be to introduce one more Executor. You can use a ScheduledExecutorService to cancel all long running tasks for example:
ExecutorService service = Executors.newFixedThreadPool(N);
ScheduledExecutorService canceller = Executors.newScheduledThreadPool(1);
public void executeTask(Callable<?> c){
final Future<?> future = service.submit(c);
canceller.schedule(new Runnable(){
public void run(){
future.cancel(true);
}
}, SECONDS_UNTIL_TIMEOUT, TimeUnit.SECONDS);
}
You could get a list of your corresponding Futures (that are created when you submit a Callable) together with its startup time.
Another task could then check every minute if there are some task running for more than a defined time and if so, invoke cancel(true) in the Future. Done futures would be removed off the list.
You can use this method
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
long timeout,
TimeUnit unit)
throws InterruptedException
and set the maximum timeout to one minute. If your thread takes more than that it is just aborted.
The problem is you can not kill/stop/suspend the java thread.
All are deprecated.
future.cancel will only considered before worker thread
So if the thread is stuck with any code execution and doesn't have the logic to consider the thread interruption, then execution will still continue.
This is even true for executorService.shutdown();.
The documentation says.
There are no guarantees beyond best-effort attempts to stop processing
actively executing tasks. For example, typical implementations will
cancel via Thread. interrupt, so any task that fails to respond to
interrupts may never terminate.
So the only solution is to log such a situation and fix the inherent issue.
Future<?> future = executor.submit(task);
try {
future.get(15, TimeUnit.MINUTES);
} catch (InterruptedException e) {
// retry waiting. iterative approach not shown here
} catch (ExecutionException e) {
// your task exploded
} catch (TimeoutException e) {
// The task is running longer than usual
// Log it for future analysis
//If the interrupt signal is handled
//OR the task is stuck in the queue itself for a long time
//then worth calling below
future.cancel(true);
}

Categories

Resources