How do you feel about the root cause of sleep interruption in Java?
I have some code:
public class MyTask implements Runnable {
@Override
public void run() {
// Some code
Thread.sleep();
// Some more code.
}
}
ExecutorService executor = Executors.newCachedThreadPool();
List<MyTask> tasks = getTasks();
for(MyTask t : tasks)
executor.execute(t);
executor.shutdownNow()
if(!executor.awaitTermination(30, TimeUnit.MINUTES)) {
TimeoutException toExc = new TimeoutException("MyAPp hung after the 30 minutes timeout was reached.") // TODO
log.error(toExc)
throw toExc
}
When I run this with multiple instances MyTask
returning from getTasks()
I get very cryptic:
[pool-3-thread-3] INFO me.myapp.MyTask - java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
...etc.
The problem here is that there is no underlying reason: the spins of the stream are simply "interrupted" at some point.
So my question is , when / why is it interrupted Thread.sleep()
, and what can I do to get the root cause of the exception?
source to share
A thread being executed by a task may be interrupted by a release
future.cancel(true);
against a Future object returned from a call executorService.submit(runnable);
If you are getting a lot of such exceptions, another possibility is that the entire executor service has been disabled with
executorService.shutdownNow();
There is no direct way of knowing which action by which the thread actually turned the flag on interrupted
.
source to share
Link to JavaDoc for Thread.sleep()
, another thread interrupted yours.
Throws:
InterruptedException - if any thread has interrupted the current thread. The interrupted status of the current thread is cleared on this exception.
The JavaDoc for InterruptedException
shows more details:
Thrown when a thread is waiting, sleeping, or otherwise busy, and the thread is interrupted before or during an action. Sometimes a method may want to check if the current thread has been interrupted, and if so, then immediately throw this exception.
source to share
As a bit of a hack, you could implement Runnable
extend instead Thread
. Then you can override interrupt
and capture the stack trace before forwarding the call.
I wouldn't recommend this for final code, but when tracking down strange interrupts, this may be the only way.
public class InterruptAwareThread extends Thread {
volatile String interruptedStack = null;
@Override
public void interrupt () {
StringWriter s = new StringWriter();
new Exception().printStackTrace(new PrintWriter(s));
interruptedStack = s.toString();
super.interrupt();
}
}
source to share