在下面给出的代码中,i.intValue
抛出NPE
。但它没有被打印出来。相反,ScheduledExecutorService
通过取消后续执行来静默终止。 为什么?
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import java.util.*;
class Concurr
{
public static void main(String[] args)
{
ScheduledExecutorService sce = Executors.newScheduledThreadPool(1);
Runnable task = new Runnable()
{
public void run()
{
System.out.print(".");
Integer i = null;
i.intValue();
}
};
final ScheduledFuture<?> future = sce.scheduleAtFixedRate(task,0,2,TimeUnit.SECONDS);
sce.schedule( new Runnable()
{
public void run()
{
future.cancel(true);
}
},10,TimeUnit.SECONDS);
}
}
最佳答案
ExecutorService
捕获(并存储)其管理的 Runnable
和 Callable
实例中引发的所有异常。
ScheduledFuture
有一个 get()
方法,如果在执行 期间抛出异常,该方法会抛出包含异常的
。如果执行被取消,它会抛出 ExecutionException
可运行CancellationException
。
做
System.out.println(future.get()); // returns null otherwise
在main
的末尾。您将得到以下输出:
.Exception in thread "main" java.util.concurrent.ExecutionException: java.lang.NullPointerException
at java.util.concurrent.FutureTask$Sync.innerGet(Unknown Source)
at java.util.concurrent.FutureTask.get(Unknown Source)
at test.Main.main(Main.java:50)
Caused by: java.lang.NullPointerException
at test.Main$1.run(Main.java:38)
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$301(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
如果您的异步任务应该返回一个值,您可以使用 Callable
而不是 Runnable
并将其传递给 ExecutorService
。您可以使用 future.get()
获取该值。
每次调用 future.get()
都会返回 Runnable
的一次执行结果。例如,您已安排任务每 5 秒运行一次。如果 16 秒后,您调用
future.get();
future.get();
future.get();
future.get();
该代码将在第四次调用时阻塞,因为所有其他调用都已完成并将返回结果(除非其中一个调用失败)。
关于java - 当 run 方法抛出 NPE 时,ScheduledExecutorService 不打印异常堆栈跟踪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18217467/