在下面给出的代码中,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);
}
}
答案 0 :(得分:1)
ExecutorService
捕获(并存储)其管理的Runnable
和Callable
个实例中抛出的所有异常。
ScheduledFuture
有一个get()
方法,如果在执行ExecutionException
期间抛出一个异常,则会抛出Runnable
。如果执行被取消,它会抛出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();
代码将在第4次调用时阻止,因为所有其他代码已经完成并且将返回结果(除非其中一个失败)。