2

在下面给出的代码中,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);
    }
}
4

1 回答 1

2

一个捕获(并存储)在它管理的实例ExecutorService中抛出的所有异常。RunnableCallable

ScheduledFuture一个get()方法,ExecutionException如果在执行Runnable. 它抛出一个CancellationExceptionif 执行被取消。

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)

如果您的异步任务应该返回一个值,您可以使用并将 aCallable而不是 a传递Runnable给。ExecutorService你会得到那个值future.get()

每次调用future.get()都会返回一次执行您的Runnable. 例如,您已安排任务每 5 秒运行一次。如果 16 秒后,你打电话

future.get();
future.get();
future.get();
future.get();

该代码将在第 4 次调用时阻塞,因为所有其他人都已经完成并且将返回结果(除非其中一个失败)。

于 2013-08-13T19:28:56.853 回答