I'm trying to implement a TimeoutTask which will terminate after a given timeout. Here is what I have:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Objects;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class TimeoutTask {
private Long timeout;
private TimeUnit unit;
public TimeoutTask(Long timeout, TimeUnit unit) {
this.timeout = timeout;
this.unit = unit;
}
public <T> T execute(Callable<T> callable) {
Objects.requireNonNull(timeout, "Timeout");
Objects.requireNonNull(unit, "Time Unit");
Objects.requireNonNull(callable, "Callable");
ExecutorService service =
Executors.newFixedThreadPool(1);
FutureTask<T> task = new FutureTask<T>(callable);
service.execute(task);
try {
return task.get(timeout, unit);
} catch (InterruptedException | ExecutionException | TimeoutException cause) {
if(cause instanceof TimeoutException) {
System.out.println("\nTimeout occured.");
task.cancel(true);
}
} finally {
System.out.println("Finally called.");
service.shutdownNow();
}
return null;
}
public static void main(String[] args) throws InterruptedException, ExecutionException, TimeoutException {
Callable<String> callable = () -> {
System.out.print("Enter something: ");
BufferedReader consoleReader =
new BufferedReader(new InputStreamReader(System.in));
String str = consoleReader.readLine();
return str;
};
TimeoutTask timeoutTask = new TimeoutTask(Long.valueOf(10), TimeUnit.SECONDS);
timeoutTask.execute(callable);
}
}
It is working and I can see the message on timeout if there is no input given. However the process doesn't get terminated. Following is the screenshot from Eclipse's console, see the highlighted portion:
When I am giving any input the process terminated immediately. I am calling the FutureTask#cancel from the catch block also from finally block I am asking to shutdown the service by making a call to ExecutorService#shoutDownNow and I can see it is printing that the finally get called.
How can I stop the process being executed any further in case of timeout?
Is there any better approach to achieve this?
I am using Java 8.
Reference:
java native Process timeout
TimeoutTask using ExecutorService
Update
In the answer of Marko Topolnik said that the cause is of non-interrupted Java IO; so I change the Callable as:
Callable<Long> callable = () -> {
long i = 0;
for(; i <Long.MAX_VALUE;i++){
}
return i;
};
For this case the same thing happened.
Note: The Callable is just a sample.
You call
String str = consoleReader.readLine();
which means you are using the classic, blocking, non-interruptible Java IO. The method keeps blocking even after the timeout and shutdownNow() can't touch it, either, because it also just tries to interrupt the thread.
BTW I have run your code and the output shows "Finally called".
Update
Your updated Callable is just as non-interruptible as the original one. You must either call a method which declares to throw InterruptedException (such as Thread.sleep()) or check Thread.interrupted() yourself in the loop.
The issue you need to solve is that System.in.read() does not response to interrupts. See how to bypass this in Heinz M. Kabutz newsletter
Related
I am reading the book Introducing Play Framework: Java Web Application Development (ISBN 978-1-4842-5645-9) and there is this example on Callable:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class CallableClient {
/**
* #param args
*/
// Step1 : Create a Runnable
public static void main(String[] args) {
Callable callableTask = new CallableTask();
// Step 2: Configure Executor
// Uses FixedThreadPool executor
ExecutorService executor = Executors.newFixedThreadPool(2);
Future<String> future = executor.submit(callableTask);
boolean listen = true;
while (listen) {
if (future.isDone()) {
String result;
try {
result = future.get();
listen = false;
System.out.println(result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
executor.shutdown();
}
}
My question is, if the computation of the Future throws and exception, will the while loop run forever?
In my opinion, yes, it will loop forever.
First, if the Future computation throws an exception, then
future.isDone()
always evaluates to true. So we reach the inside of the if, where the stopping condition can be set. Still Ok.
Second, as per future documentation, when reaching line
result = future.get();
it will always throw ExecutionException because the computation threw an exception. This exception is caught in the try-catch block, without reaching the stopping condition precondition, which is
listen = false
Lastly, the above will create an endless cycle.
Is there any mistake in my assumptions or is the author of the example really wrong?
The program mentioned above cycles forever, if the callable throws an exception.
This is a code snippet with the callable that throws an exceptions. Executing compiled snippet loops forever.
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class CallableClient {
public static class CallableTask implements Callable<String> {
#Override
public String call() throws Exception {
throw new Exception();
}
}
public static void main(String[] args) {
Callable<String> callableTask = new CallableTask();
ExecutorService executor = Executors.newFixedThreadPool(2);
Future<String> future = executor.submit(callableTask);
boolean listen = true;
while (listen) {
if (future.isDone()) {
String result;
try {
result = future.get();
listen = false;
System.out.println(result);
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
executor.shutdown();
}
}
I am using a ScheduledExecutorService to which I add both submit Runnables as well as scheduled Runnables (using scheduleWithFixedDelay).
The intention is to have very long running processes and thus non of my runnables have a defined lifetime. I basically want the main thread to only react to exceptions and interruptions.
The scheduled tasks are critical, e.g. generating heatbeats, and thus if any thread throw a runtimeexception I want to log the exception, abort all other threads and close the program.
How should I handle the exceptions? The ScheduledExecutorService swallows all the exceptions unless I run Future.get().
Looping through the futures, like below, does not work. If the first item in the futures list doesn't return any errors that will block the thread from listening on the other threads that might return error.
for (Future<?> future : futures) {
future.get();
}
One option would be looping through the futures asking if they are done, like below, but I don't really like this solution. I need to add a thread sleep and thus the response to an exception is delayed.
boolean allActive = true;
while (allActive) {
for (Future<?> future : futures) {
if (!future.isDone()) {
allActive = false;
break;
}
}
Thread.sleep(50);
}
What other options do I have? Or am I approaching the problem wrong?
Shouldn't I use a ScheduledExecutorService at all and implement the schedule myself in my own thread?
Example code, try change the order to the future list! I want the behavior you get if you add handle before handle2 but the order of the list shouldn't matter:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Test {
private static int i = 0;
public static void main(String[] args) throws Exception {
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
Future<?> handle = scheduler.scheduleWithFixedDelay(new Runnable() {
public void run() {
System.out.println("No exception!");
if (i > 2) {
System.out.println("Exception!");
throw new RuntimeException("foo");
}
i++;
}
}, 0, 500, TimeUnit.MILLISECONDS);
Future<?> handle2 = scheduler.scheduleWithFixedDelay(new Runnable() {
public void run() {
System.out.println("Running!");
}
}, 0, 500, TimeUnit.MILLISECONDS);
List<Future<?>> futures = new ArrayList<>();
futures.add(handle2);
futures.add(handle);
try {
for (Future<?> future : futures) {
future.get();
}
} catch (Exception e) {
scheduler.shutdownNow();
System.out.println(scheduler.awaitTermination(1, TimeUnit.SECONDS));
System.out.println("Shuwdown complete");
e.printStackTrace();
}
}
}
You can do it with a Listener or Observer-Like pattern:
interface IFutureListener{
void onException( Throwable t );
}
final IFutureListener errHandler = new IFutureListener(){
#override public void onException( Throwable t ){
// shutdown Service here
}
};
// ...
Future<?> handle = scheduler.scheduleWithFixedDelay(new Runnable() {
final IFutureListener callback = errHandler;
public void run() {
try{
System.out.println("No exception!");
if (i > 2) {
System.out.println("Exception!");
throw new RuntimeException("foo");
}
i++;
}
catch( Exception ex ){
callback.onException(ex);
}
}
}, 0, 500, TimeUnit.MILLISECONDS);
You still might need some tweaks to this, but this is the gist of it.
Guava's ListenableFuture as #dimo414 writes in comment will give you something similar. But if you do not want / are not allowed to use 3rd parties, this is a way you can implement it yourself.
Thanks to #efekctive: I also suggest logging exceptions. They should almost never just be swallowed silently except you know exactly what you are doing.
There are two approaches to submitting and polling task for result
FutureTask futureTask = new FutureTask<String>(callable);
Use combination of Callable and Future and submit on ExecutorService. Retrieve result using future.get().
Future future = service.submit(callable);
Use FutureTask. This will wrap Callable and then retrieve result using FutureTask.
service.execute(task);
What is the advantage of using FutureTask over Callable + Future combination ?
Almost certainly none at all. A quick browse on GrepCode of the AbstractExecutorService shows each of these methods are simply helper methods that ultimately wrap the Callable/Runnable in a Future for you.
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
return new FutureTask<T>(runnable, value);
}
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
return new FutureTask<T>(callable);
}
public Future<?> submit(Runnable task) {
// ...
RunnableFuture<Object> ftask = newTaskFor(task, null);
execute(ftask);
return ftask;
}
public <T> Future<T> submit(Runnable task, T result) {
// ...
RunnableFuture<T> ftask = newTaskFor(task, result);
execute(ftask);
return ftask;
}
public <T> Future<T> submit(Callable<T> task) {
// ...
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
}
Using Future we can find out the status of the Callable task and get the returned Object. It provides get() method that can wait for the Callable to finish and then return the result.
Future provides cancel() method to cancel the associated Callable task. There is an overloaded version of get() method where we can specify the time to wait for the result, it’s useful to avoid current thread getting blocked for longer time. There are isDone() and isCancelled() methods to find out the current status of associated Callable task.
Here is a simple example of Callable task that returns the name of thread executing the task after one second. We are using Executor framework to execute 100 tasks in parallel and use Future to get the result of the submitted tasks.
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class MyCallable implements Callable<String> {
#Override
public String call() throws Exception {
Thread.sleep(1000);
//return the thread name executing this callable task
return Thread.currentThread().getName();
}
public static void main(String args[]){
//Get ExecutorService from Executors utility class, thread pool size is 10
ExecutorService executor = Executors.newFixedThreadPool(10);
//create a list to hold the Future object associated with Callable
List<Future<String>> list = new ArrayList<Future<String>>();
//Create MyCallable instance
Callable<String> callable = new MyCallable();
for(int i=0; i< 100; i++){
//submit Callable tasks to be executed by thread pool
Future<String> future = executor.submit(callable);
//add Future to the list, we can get return value using Future
list.add(future);
}
for(Future<String> fut : list){
try {
//print the return value of Future, notice the output delay in console
// because Future.get() waits for task to get completed
System.out.println(new Date()+ "::"+fut.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
//shut down the executor service now
executor.shutdown();
}
}
Where as FutureTask is base concrete implementation of Future interface and provides asynchronous processing. It contains the methods to start and cancel a task and also methods that can return the state of the FutureTask as whether it’s completed or cancelled. We need a callable object to create a future task and then we can use Java Thread Pool Executor to process these asynchronously.
Let’s see the example of FutureTask with a simple program.
Since FutureTask requires a callable object, we will create a simple Callable implementation.
public class MyCallable implements Callable<String> {
private long waitTime;
public MyCallable(int timeInMillis){
this.waitTime=timeInMillis;
}
#Override
public String call() throws Exception {
Thread.sleep(waitTime);
//return the thread name executing this callable task
return Thread.currentThread().getName();
}
}
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class FutureTaskExample {
public static void main(String[] args) {
MyCallable callable1 = new MyCallable(1000);
MyCallable callable2 = new MyCallable(2000);
FutureTask<String> futureTask1 = new FutureTask<String>(callable1);
FutureTask<String> futureTask2 = new FutureTask<String>(callable2);
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.execute(futureTask1);
executor.execute(futureTask2);
while (true) {
try {
if(futureTask1.isDone() && futureTask2.isDone()){
System.out.println("Done");
//shut down executor service
executor.shutdown();
return;
}
if(!futureTask1.isDone()){
//wait indefinitely for future task to complete
System.out.println("FutureTask1 output="+futureTask1.get());
}
System.out.println("Waiting for FutureTask2 to complete");
String s = futureTask2.get(200L, TimeUnit.MILLISECONDS);
if(s !=null){
System.out.println("FutureTask2 output="+s);
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}catch(TimeoutException e){
//do nothing
}
}
}
}
FutureTask<T> class contains an additional " done()" method so we can override the done() method, then add the FutureTask object to the ExecutorService, so the done() method will invoke when the FutureTask completed immediately.
The title pretty much sums it.
I want to know the concept and idea of callable . I have read a question here on difference between callable and runnable. but no one show code and give detail what a callable is. I don't want to know the difference between them. I want to know ,
What is a callable ?
When to use them and how to use them .
When they come in action for
Android.
You can check this example:
In this example Callable task returns the name of thread executing the task after one second. We are using Executor framework to execute 100 tasks in parallel and use Future to get the result of the submitted tasks.
package com.journaldev.threads;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class MyCallable implements Callable<String> {
#Override
public String call() throws Exception {
Thread.sleep(1000);
//return the thread name executing this callable task
return Thread.currentThread().getName();
}
public static void main(String args[]){
//Get ExecutorService from Executors utility class, thread pool size is 10
ExecutorService executor = Executors.newFixedThreadPool(10);
//create a list to hold the Future object associated with Callable
List<Future<String>> list = new ArrayList<Future<String>>();
//Create MyCallable instance
Callable<String> callable = new MyCallable();
for(int i=0; i< 100; i++){
//submit Callable tasks to be executed by thread pool
Future<String> future = executor.submit(callable);
//add Future to the list, we can get return value using Future
list.add(future);
}
for(Future<String> fut : list){
try {
//print the return value of Future, notice the output delay in console
// because Future.get() waits for task to get completed
System.out.println(new Date()+ "::"+fut.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
//shut down the executor service now
executor.shutdown();
}
}
You may also check Using Callable to Return Results From Runnables
Callable is similar to Runnable but it returns a result and may throw an exception.
Use them when you expect your asynchronous tasks to return result.
The returned result of asynchronous computation is represented by a Future.
You can check this simple example implemented using FutureTask (which implements RunnableFuture and Future)
public static void main(String[] args) {
// providing an anonymous callable to FutureTask
RunnableFuture<String> future = new FutureTask<String>(
new Callable<String>() {
#Override
public String call() throws InterruptedException {
System.out.println("sleeping");
Thread.sleep(2000);
System.out.println("returning");
return "hello-world";
}
});
Thread t = new Thread(future);
t.start();
try {
// the get Waits if necessary for the computation to complete
System.out.println(future.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
The output of the following simple code is a little odd to me.
it miss out some of the numbers between 0 and 100 to print on the console.
could anyone explain why it omit to print? i am completely new to concurrency programming.
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.junit.Test;
public class SimpleTest {
#Test
public void testSimple() throws Exception {
ExecutorService executorService = Executors.newFixedThreadPool(10);
for(int i = 0; i <= 100; i++) {
executorService.execute(new SimpleRunnable(i));
}
executorService.shutdown();
}
}
class SimpleRunnable implements Runnable {
int i;
public SimpleRunnable(int i) {
this.i = i;
}
public void run() {
synchronized(System.out) {
System.out.println(i);
}
}
}
You should wait for the executor service to finish after calling shutdown
executorService.shutdown();
executor.awaitTermination(30, TimeUnit.SECONDS); // Wait for the tasks to finish.
// and flush!
System.out.flush();
I suspect the threads created are daemon threads, which do not prevent a JVM shutdown. Since the threads are kicked off and forgotten, after your call to shutdown, the method returns and then the JVM exits because there is nothing else to do. Unfinished work never gets done.
As Elliot pointed out, use the awaitTermination method:
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html#awaitTermination(long, java.util.concurrent.TimeUnit)