[英]Printing the stack trace from a newly created thread when an unchecked exception is thrown in Eclipse
Why am I unable to see the stack trace in Eclipse's console when an unchecked Exception is thrown from a thread different from the main thread? 当从与主线程不同的线程抛出未经检查的异常时,为什么在Eclipse的控制台中看不到堆栈跟踪?
For example: 例如:
ScheduledThreadPoolExecutor scheduledExecutor;
scheduledExecutor.scheduleAtFixedRate(new Log(), 0, LOGGING_FREQUENCY_MS, TimeUnit.MILLISECONDS);
public class Log implements Runnable {
public void run() {
//NullPointerException is thrown
}
}
I get no output. 我没有输出。 But if I do:
但是,如果我这样做:
ScheduledThreadPoolExecutor scheduledExecutor;
scheduledExecutor.scheduleAtFixedRate(new Log(), 0, LOGGING_FREQUENCY_MS, TimeUnit.MILLISECONDS);
public class Log implements Runnable {
public void run() {
try {
//NullPointerException is thrown
}catch(Exception e){
e.printStackTrace();
}
}
}
I can see the stack trace. 我可以看到堆栈跟踪。
Why? 为什么?
EDIT: Follow-up question: What would be the easiest way to print the exceptions thrown by thread-pool threads? 编辑:后续问题:什么是打印线程池线程抛出的异常的最简单方法? Adding try-catch to every single Runnable is of course really ugly.
将try-catch添加到每个单个Runnable当然很丑。
Why am I unable to see the stack trace in Eclipse's console when an unchecked Exception is thrown from a thread different from the main thread?
当从与主线程不同的线程抛出未经检查的异常时,为什么在Eclipse的控制台中看不到堆栈跟踪?
Because it is unchecked. 因为未选中。 By default there is nothing that prints the exceptions thrown by thread-pool threads.
默认情况下,没有任何东西可以打印线程池线程抛出的异常。
If you want to see the exception then you need to do something like: 如果要查看异常,则需要执行以下操作:
Future future = scheduledExecutor.submit(...);
...
try {
// wait for the run() method to finish normally or with a throw
future.get();
} catch (ExecutionException e) {
// the cause of this exception is the one that is thrown by the run()
Throwable cause = e.getCause();
cause.printStackTrace();
}
EDIT: Follow-up question: What would be the easiest way to print the exceptions thrown by thread-pool threads?
编辑:后续问题:什么是打印线程池线程抛出的异常的最简单方法? Adding try-catch to every single Runnable is of course really ugly.
将try-catch添加到每个单个Runnable当然很丑。
You don't need to add the try/catch to the Runnable
, you add it to the guy who starts the pool. 您无需将try / catch添加到
Runnable
,而将其添加到启动池的家伙。
Another solution would be to write a little RunnableWrapper
which prints out exceptions: 另一个解决方案是编写一个小的
RunnableWrapper
来打印出异常:
public void RunnableWrapper implements Runnable {
private Runnable delegate;
public RunnableWrapper(Runnable delegate) {
this.delegate = delegate;
}
public void run() {
try {
delegate.run();
} catch (Throwable t) {
t.printStackTrace();
}
}
}
Then you can do: 然后,您可以执行以下操作:
scheduledExecutor.submit(new RunnableWrapper(myTask));
But the future.get();
但是
future.get();
is the typical way of solving this. 是解决此问题的典型方法。
Because the Executor has "swallowed" the exception. 因为执行程序已“吞噬”了异常。 You can see if you got one by querying the returned future:
您可以通过查询返回的Future来查看是否得到了:
Future<?> f = scheduledExecutor.scheduleAtFixedRate(new Log(),...);
try {
f.get();
} catch (ExecutionException e) {
Throwable actualException = e.getCause();
}
Note that f.get()
will block until the task is cancelled or throws an exception so you will probably want to call it in a separate thread. 请注意,
f.get()
将阻塞,直到任务被取消或引发异常,因此您可能希望在单独的线程中调用它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.