The code that I have creates a Callable instance and using ExecutorService a new thread is being created. I want to kill this thread after certain amount of time if the thread is not done with its execution. After going through the jdk documentation I've realized that Future.cancel() method can be used to stop the execution of the thread, but to my dismay its not working. Of course future.get() method is sending an interrupt to the Thread after the stipulated time (in my case its 2 seconds) and even the thread is receiving this interrupt but this interruption is taking place only once the thread is done with its execution completely. But I want to kill the thread after 2 seconds.
Could anyone help me how to achieve this.
Testclass code:
====================================
public class TestExecService {
public static void main(String[] args) {
//checkFixedThreadPool();
checkCallablePool();
}
private static void checkCallablePool()
{
PrintCallableTask task1 = new PrintCallableTask("thread1");
ExecutorService threadExecutor = Executors.newFixedThreadPool(1);
Future<String> future = threadExecutor.submit(task1);
try {
System.out.println("Started..");
System.out.println("Return VAL from thread ===>>>>>" + future.get(2, TimeUnit.SECONDS));
System.out.println("Finished!");
}
catch (InterruptedException e)
{
System.out.println("Thread got Interrupted Exception ==============================>>>>>>>>>>>>>>>>>>>>>>>>>");
//e.printStackTrace();
}
catch (ExecutionException e)
{
System.out.println("Thread got Execution Exception ==============================>>>>>>>>>>>>>>>>>>>>>>>>>");
}
catch (TimeoutException e)
{
System.out.println("Thread got TimedOut Exception ==============================>>>>>>>>>>>>>>>>>>>>>>>>>");
future.cancel(true);
}
threadExecutor.shutdownNow();
}
}
Callable Class code:
===================================================================
package com.test;
import java.util.concurrent.Callable;
public class PrintCallableTask implements Callable<String> {
private int sleepTime;
private String threadName;
public PrintCallableTask(String name)
{
threadName = name;
sleepTime = 100000;
}
@Override
public String call() throws Exception {
try {
System.out.printf("%s going to sleep for %d milliseconds.\n", threadName, sleepTime);
int i = 0;
while (i < 100000)
{
System.out.println(i++);
}
Thread.sleep(sleepTime); // put thread to sleep
System.out.printf("%s is in middle of execution \n", threadName);
} catch (InterruptedException exception) {
exception.printStackTrace();
}
System.out.printf("%s done sleeping\n", threadName);
return "success";
}
}
Your code does everything right. The only problem is that you're not checking Thread.isInterrupted
in the while
loop. The only way for thread to get the message is to get to the blocking call Thread.sleep
which will immediately throw InterruptedException
.
If loop is lengthy it can take some time. That's exactly why your code is a little bit unresponsive.
Check for interruption status, say, every 10,000 iterations:
while (i < 100000) {
if (i % 10000 == 0 && Thread.currentThread().isInterrupted())
return "fail";
System.out.println(i++);
}
InterruptedException
is for lengthy blocking methods. Thread.isInterrupted
is for everything else.