2

以下のコードでi.intValueは、 throwingNPEです。しかし、それは印刷されていません。代わりに、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()メソッドがあります。実行がキャンセルされた場合はスローします。ExecutionExceptionRunnableCancellationException

行う

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)

非同期タスクが値を返す必要がある場合は、 a のCallable代わりに aRunnableを使用して渡すことができます。ExecutorServiceでその値を取得しますfuture.get()

を呼び出すたびにfuture.get()、 を 1 回実行した結果が返されますRunnable。たとえば、タスクを 5 秒ごとに実行するようにスケジュールしたとします。16 秒後にコールすると、

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

コードは 4 回目の呼び出しでブロックされます。これは、他のすべての呼び出しが既に終了しており、結果が返されているためです (そのうちの 1 つが失敗しない限り)。

于 2013-08-13T19:28:56.853 に答える