Why does this code not print an exception stack trace?
public class Playground {
/**
* @param args
*/
public static void main(String[] args) {
startThread();
}
private static void startThread() {
ScheduledExecutorService timer = Executors
.newSingleThreadScheduledExecutor();
Runnable r = new Runnable() {
int dummyInt = 0;
boolean dummyBoolean = false;
@Override
public void run() {
dummyInt = Integer.parseInt("AAAA");
if (dummyBoolean) {
dummyBoolean= false;
} else {
dummyBoolean= true;
}
}
};
timer.scheduleAtFixedRate(r, 0, 100, TimeUnit.MILLISECONDS);
}
}
How can I get it to?
I would expect to see this:
java.lang.NumberFormatException: For input string: "AAAA"
at java.lang.NumberFormatException.forInputString(Unknown Source)
at java.lang.Integer.parseInt(Unknown Source)
at java.lang.Integer.parseInt开发者_开发技巧(Unknown Source)
at Playground$1.run(Playground.java:25)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask$Sync.innerRunAndReset(Unknown Source)
at java.util.concurrent.FutureTask.runAndReset(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
The executor probably sets its own uncaught exception handler on the thread, so the stack trace won't be printed to the console. If an exception is thrown in the Runnable
you can get it from the ScheduledFuture
object returned by the scheduleAtFixedRate
method:
ScheduledFuture<?> future = timer.scheduleAtFixedRate(r, 0, 100, TimeUnit.MILLISECONDS);
try {
future.get();
} catch (ExecutionException e) {
Throwable cause = e.getCause();
cause.printStackTrace();
}
The executor service tends to swallow exceptions for some reason. It can make debugging quite challenging. Just add a try catch around the contents of your run method like this:
public void run() {
try
dummyInt = Integer.parseInt("AAAA");
if (dummyBoolean) {
dummyBoolean= false;
} else {
dummyBoolean= true;
}
} catch (Exception e){
e.printStackTrace();
}
}
Here's a related question.
There is a similar question that provides an answer Unhandled exceptions with Java scheduled executors here on StackOverflow.
Basically what you can read in the scheduleAtFixedRate() javadoc:
If any execution of the task encounters an exception, subsequent executions are suppressed
So, I'd generalise from here that you never get to see your exceptions when submitting tasks through ScheduledExecutorService.scheduleAtFixedRate()
.
精彩评论