My code snippet:
ExecutorService executor = Executors.newSingleThreadExecutor();
try {
Task t = new Task(response,inputToPass,pTypes,unit.getInstance(),methodName,unit.getUnitKey());
Future<SCCallOutResponse> fut = executor.submit(t);
response = fut.get(unit.getTimeOut(),TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
// if the task is still running, a TimeOutException will occur while fut.get()
cat.error("Unit " + unit.getUnitKey() + " Timed Out");
response.setVote(SCCallOutConsts.TIMEOUT);
} catch (InterruptedException e) {
cat.error(e);
} catch (ExecutionException e) {
cat.error(e);
} finally {
executor.shutdown();
}
How should i handle the InterruptedException and ExecutionException in the code?
And in what cases, are these exceptions thrown?
ExecutionException and InterruptedException are two very different things.
ExecutionException wraps whatever exception the thread being executed threw, so if your thread was, for instance, doing some kind of IO that caused an IOException to get thrown, that would get wrapped in an ExecutionException and rethrown.
An InterruptedException is not a sign of anything having gone wrong. It is there to give you a way to let your threads know when it's time to stop so that they can finish up their current work and exit gracefully. Say I want my application to stop running, but I don't want my threads to drop what they're doing in the middle of something (which is what would happen if I made them daemon threads). So when the application is being shutdown, my code calls the interrupt method on these threads, which sets the interrupt flag on them, and the next time those threads are waiting or sleeping they check the interrupt flag and throw an InterruptedException, which I can use to bail out of whatever infinite-loop processing/sleeping logic the threads are engaged in. (And if the thread doesn't wait or sleep, it can just check the interrupt flag periodically.) So it is an instance of an exception being used to change the logical flow. The only reason you would log it at all is in an example program to show you what's happening, or if you're debugging a problem where interrupt logic is not working correctly.
InterruptedException will be thrown if interrupt is called on the waiting thread before the computation has completed.
ExecutionException will be thrown if the computation involved (Task in this case) throws an exception itself.
How you want to handle this will entirely depend on your application.
EDIT: Here's a demonstration of being interrupted:
import java.util.concurrent.*;
public class Test
{
public static void main(String[] args) throws Exception
{
ExecutorService executor = Executors.newFixedThreadPool(2);
Future<String> future = executor.submit(new SlowCallable());
executor.submit(new Interruptor(Thread.currentThread()));
try
{
System.out.println(future.get());
}
catch (InterruptedException e)
{
System.out.println("I was interrupted");
}
}
private static class Interruptor implements Callable<String>
{
private final Thread threadToInterrupt;
Interruptor(Thread threadToInterrupt)
{
this.threadToInterrupt = threadToInterrupt;
}
public String call() throws Exception
{
Thread.sleep(2000);
threadToInterrupt.interrupt();
return "interrupted other thread";
}
}
private static class SlowCallable implements Callable<String>
{
public String call() throws Exception
{
Thread.sleep(5000);
return "finished";
}
}
}
Sample code to return three types of Exceptions.
import java.util.concurrent.*;
import java.util.*;
public class ExceptionDemo{
public static void main(String args[]){
int poolSize=1;
int maxPoolSize=1;
int queueSize=30;
long aliveTive=60;
ArrayBlockingQueue<Runnable> queue= new ArrayBlockingQueue<Runnable>(queueSize);
ThreadPoolExecutor executor= new ThreadPoolExecutor(poolSize,maxPoolSize,aliveTive,
TimeUnit.MILLISECONDS,queue);
List<Future> futures = new ArrayList<Future>();
for ( int i=0; i < 5; i++){
futures.add(executor.submit(new RunnableEx()));
}
for ( Iterator it = futures.iterator(); it.hasNext();){
try {
Future f = (Future)it.next();
f.get(4000,TimeUnit.MILLISECONDS);
}catch(TimeoutException terr){
System.out.println("Timeout exception");
terr.printStackTrace();
}
catch(InterruptedException ierr){
System.out.println("Interrupted exception:");
ierr.printStackTrace();
}catch(ExecutionException err){
System.out.println("Exeuction exception:");
err.printStackTrace();
Thread.currentThread().interrupt();
}
}
executor.shutdown();
}
}
class RunnableEx implements Runnable{
public void run() {
// code in here
System.out.println("Thread name:"+Thread.currentThread().getName());
try{
Random r = new Random();
if (r.nextInt(2) == 1){
Thread.sleep(2000);
}else{
Thread.sleep(4000);
}
System.out.println("eee:"+1/0);
}catch(InterruptedException irr){
irr.printStackTrace();
}
}
}
output:
Thread name:pool-1-thread-1
Timeout exception
Thread name:pool-1-thread-1
java.util.concurrent.TimeoutException
at java.util.concurrent.FutureTask.get(FutureTask.java:201)
at ExceptionDemo.main(ExceptionDemo.java:20)
Thread name:pool-1-thread-1
Exeuction exception:
java.util.concurrent.ExecutionException: java.lang.ArithmeticException: / by zero
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:202)
at ExceptionDemo.main(ExceptionDemo.java:20)
Caused by: java.lang.ArithmeticException: / by zero
at RunnableEx.run(ExceptionDemo.java:49)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
Interrupted exception:
java.lang.InterruptedException
at java.util.concurrent.FutureTask.awaitDone(FutureTask.java:400)
at java.util.concurrent.FutureTask.get(FutureTask.java:199)
at ExceptionDemo.main(ExceptionDemo.java:20)
Timeout exception
java.util.concurrent.TimeoutException
at java.util.concurrent.FutureTask.get(FutureTask.java:201)
Thread name:pool-1-thread-1
at ExceptionDemo.main(ExceptionDemo.java:20)
Thread name:pool-1-thread-1
Timeout exception
java.util.concurrent.TimeoutException
at java.util.concurrent.FutureTask.get(FutureTask.java:201)
at ExceptionDemo.main(ExceptionDemo.java:20)
TimeoutException : Exception thrown when a blocking operation times out.
In above example, some tasks are taking more time (due to 4 seconds sleep) and blocking operation of get() on Future
Either increase the time-out or optimize Runnable task.
ExecutionException: Exception thrown when attempting to retrieve the result of a task that aborted by throwing an exception => The computation threw an exception
In above example, this Exception is simulated through ArithmeticException: / by zero
Generally, you should catch it fix the root cause if it is trivial as quoted in the example.
InterruptedException: Thrown when a thread is waiting, sleeping, or otherwise occupied, and the thread is interrupted, either before or during the activity.
In above example, this Exception is simulated by interrupting current Thread during ExecutionException.
Generally, you should catch it don't act on it.
Related
In the following scenario my task throws an exception. I was excepting that after one request my pool would not be able to process any further requests but it is not happening. How does thread pool behaves in this scenario? How communication of exception happens from Pool thread to main application thread?
public class CallableClass implements Callable<String> {
#Override
public String call() throws Exception {
throw new RuntimeException();
}
}
class Test {
ExecutorService executor = Executors.newFixedThreadPool(1);
public void execute(){
try {
System.out.println(executor);
Future<String> future = executor.submit(new Task());
System.out.println(executor);
future.get();
}catch(Exception e) {
System.out.println(executor);
e.printStackTrace();
}
}
}
You could check it out by printing the name of the currently executing thread:
#Override
public String call() throws Exception {
System.out.println(Thread.currentThread().getName());
...
}
How does thread pool behaves in this scenario?
The worker notifies the executor service about the exception occurred when it was working. But there is no reason to remove that worker from the ThreadPoolExecutor#workers set. It will continue its work if there is a need.
You shouldn't see any failures of the executor service. It's going to replace an invalid worker (or a thread) with a valid one if something wrong happens:
If any thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks.
ExecutorService.newFixedThreadPool(int) [JDK 9]
How communication of exception happens from Pool thread to main application thread?
Any exception thrown from a Callable#call is being wrapped by an ExecutionException and is popped up to the caller:
#throws ExecutionException if the computation threw an exception
Future.get() [JDK 9]
An example of cheching whether ExecutionException#getCause is a RuntimeException instance:
} catch (ExecutionException e) {
Throwable cause = e.getCause();
if (cause != null && cause instanceof RuntimeException) {
System.out.println("A RuntimeException was thrown.");
}
}
I am trying to understand interrupting threads within an ExecutorService and I can't figure out why the following MyNeverEndingRunnable class doesn't get the interrupt signal. I have a class that implements Runnable and simply prints and waits in a loop until it is interrupted:
class MyNeverEndingRunnable
implements Runnable
{
int count = 0;
#Override
public void run()
{
while (true)
{
System.out.printf("[%d]:%d\n", Thread.currentThread().getId(), ++count);
try { Thread.sleep(5000L); } catch (Exception ignored) {}
if (Thread.interrupted())
{
break;
}
}
}
}
I spawn a few of these threads then call shutdownNow() on my ExecutorService which should call interrupt on each of the running threads but the below code continues to run forever:
int threadCount = 5;
ExecutorService executorService = Executors.newFixedThreadPool(threadCount);
Future[] threads = new Future[threadCount];
for (int k = 0; k < threadCount; ++k)
{
threads[k] = executorService.submit(new MyNeverEndingRunnable());
}
Thread.sleep(20000L);
executorService.shutdownNow();
while (!executorService.isShutdown()) Thread.sleep(1000L);
Does anyone know what I am doing wrong here?
From the Javadoc:
InterruptedException - if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown. [My emphasis]
NB There's nothing that actually guarantees that threads are interrupted by shutdownNow(). It just describes that as a 'typical implementation'.
Your code is a little strange. Try this:
try
{
Thread.sleep(5000L);
}
catch (InterruptedException exc)
{
break;
}
and remove the Thread.interrupted() test.
Read the Javadoc on Thread.sleep():
Throws:
...
InterruptedException - if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.
As soon as the exception is thrown, it's no longer interrupted. In your case, you can immediately break out of the loop and let the thread die, as #EJP suggested. But if your code doesn't have ownership of the thread (e.g. a separate method), you'll want to make sure the interruption is propagated to the caller, either by propagating the exception, or by re-interrupting:
try {
while (true) {
System.out.printf("[%d]:%d\n", Thread.currentThread().getId(), ++count);
Thread.sleep(5000L);
}
} catch (InterruptedException notIgnored)
Thread.currentThread().interrupt();
}
Or similarly:
while (!Thread.currentThread().isInterrupted()) {
System.out.printf("[%d]:%d\n", Thread.currentThread().getId(), ++count);
try {
Thread.sleep(5000L);
} catch (InterruptedException notIgnored)
Thread.currentThread().interrupt();
}
}
In java, I would like to determine the current stack of the thread which populates the result of the future when a TimeoutException occurs. It seems that the top entry in the stack trace provided by a TimeoutException only indicates where future.get() was invoked, not the state of the background thread. For example:
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new Callable<String>() {
#Override
public String call() throws Exception {
Thread.sleep(10000);
return "";
}
});
try {
future.get(1, TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
e.printStackTrace();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
In this example I've found that the top entry is the future.get(1, TimeUnit.MILLISECONDS) entry, not the Thread.sleep(10000). I would like the stack trace to indicate Thread.sleep(10000) since this is what is currently being executed. Is there an elegant way of doing this?
I've found that if there is an actual execution problem, then the ExecutionException.printStackTrace() will indicate where the problem occurred in the background thread.
If you had a reference, t, to the Thread was running the task, you could call t.getStackTrace(); but the standard library ExecutorService implementations aren't going to tell you what thread is running the task.
You could have the task itself record what thread is running it:
class MyTask implements Callable<String> {
private volatile Thread executorThread;
#Override
String call() {
executorThread = Thread.currentThread(); // not getCurrentThread()
Thread.sleep(10000);
return "";
}
Thread getExecutorThread() {
return executorThread;
}
}
That way, when your main thread times out, it could call myTask.getExecutorThread().getStackTrace();
...
MyTask myTask = new MyTask();
Future<String> future = executor.submit(myTask);
...
} catch (InterruptedException | ExecutionException e) {
StackTraceElement[] stack = myTask.getExecutorThread().getStackTrace();
for (StackTraceElement element : stack) {
...print it...
}
}
You cant get the trace of that exception.
Because In that exception doesnt have cause and suppressed exception.
Suppose I have a method as follows:
public void poll(Callable<Boolean> callable) {
ScheduledExecutorService service = Executors.newSingleThreadedScheduledExecutor();
Future<Boolean> future = service.schedule(callable, 0L, TimeUnit.MILLISECONDS);
try {
while (!future.get()) {
future = service.schedule(callable, 5L, TimeUnit.MINUTES);
}
} catch (ExecutionException e) {
// ...
} catch (InterruptedException e) {
// ...
} finally {
service.shutdown();
}
}
How does an InterruptedException ever get thrown (and caught in poll())? Anything thrown by the callable (including InterruptedException, right?) would be an ExecutionException, we never cancel any futures, and the service's shutdownNow() is never called.
Aside: being what it is, is it possible to make this polling method more bulletproof against things like InterruptedException?
The InterruptedException would be thrown by get while waiting (blocking) for the callable to finish.
I'm not sure what you mean by bulletproof, you have to handle the possibility of the exception being thrown.
InterruptedException can be thrown by the thread which called get and is waiting for completion, not by the callable
Why doesn't setting the interrupt bit in a Callable cause the Future that represents the Callable to throw a TimeoutException when Future.get() is called?
public class ExecutorServiceTest extends MockitoTestCase {
private static CountDownLatch latch1 = new CountDownLatch(1);
class TaskChecksForInterruptedExcAndDoesSetInterruptedBit implements Callable<String> {
#Override
public String call() {
latch1.countDown();
while (!Thread.currentThread().isInterrupted()) {
}
Thread.currentThread().interrupt();
return "blah";
}
}
void testInterrupt() throws Exception {
ExecutorService pool = Executors.newFixedThreadPool(numThreads);
Future<String> future = pool.submit(new TaskChecksForInterruptedExcAndDoesSetInterruptedBit());
latch1.await(); // Don't interrupt the Callable until it actually starts processing
pool.shutdownNow();
try {
future.get(100, TimeUnit.MILLISECONDS);
} catch (final TimeoutException e) {
// Why doesn't this get called!
return;
}
fail();
}
}
the shutdownNow() call attempts to interrupt all running tasks. In this case the interruption is detected in your busy loop, so the code continues and the Callable returns "blah" (and not an exception)
TimeoutException, according to the spec, is thrown only if the thread waits for the complete timeout period, but no result becomes available. Interruption doesn't fit into this scenario.
Your usage of CountDownLatch is incorrect. You decrement it, but I see no call to latch1.await()