2017-05-28 7 views
3

無停電ようだ:上記の実装ではCompletableFuture :: joinを中断するには?完了していないとき、私はCompletableFutureが::参加していることがわかりました

// CompletableFuture::join implementation from JDK 8 sources 
public T join() { 
    Object r; 
    return reportJoin((r = result) == null ? waitingGet(false) : r); 
} 

waitingGet(false)は、作業スレッドの割り込みフラグを無視して待ってまいります。私はどのようにCompletableFuture :: joinというスレッドを中断することができるのだろうかと思っています。

+1

これはあなたが探しているものかどうか疑問に思っています。https://stackoverflow.com/questions/43389894/recursively-cancel-an-alloff-completablefuture/43391133#43391133 – Eugene

+1

@Eugeneこのリンクをご利用いただきありがとうございます。私は 'CompletableFuture :: cancel'がスレッドを中断しないことを知っています。私がしたいのは、 'CompletableFuture :: join'オペレーションでブロックするスレッドを中断することです。たぶん私は私の質問をより明確に記述するべきでしょう。 – phil

答えて

5

中断をサポートしたい場合はjoin()を使用しないでください。代わりにget()を使用してください。インターフェースCompletionStageから来

  • join()

    get()一方Future
  • join()が中断される可能性がありますExecutionException
  • get()でそれらをラップCompletionExceptionget()一方で例外をラップしてから投げるでしょうフォームインタフェースに来る:基本的に彼らは除いて同じですInterruptedException

中断するものはFutureではなくThreadです。例えば、それはmyFuture.get()で待っている間に、次のコードは、メインスレッドを中断:

CompletableFuture<Void> myFuture = new CompletableFuture<>(); 
Thread mainThread = Thread.currentThread(); 
CompletableFuture.runAsync(() -> { 
    try { 
     Thread.sleep(1000); 
     System.out.println("Interrupting…"); 
     mainThread.interrupt(); 
     Thread.sleep(1000); 
     System.out.println("Completing"); 
     myFuture.complete(null); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
}); 
try { 
    myFuture.get(); 
    System.out.println("Get succeeded"); 
} catch (Exception e) { 
    System.out.println("Get failed"); 
    e.printStackTrace(); 
} 

出力:あなたはjoin()によってget()を交換する場合

Interrupting… 
Get failed 
java.lang.InterruptedException 
    at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:347) 
    at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1895) 
    at CompletableFutureInteruption.main(CompletableFutureInteruption.java:37) 
    … 

、割り込みは実際に動作しません。

+2

'join()'と 'get()'の違いを教えていただきありがとうございます。 – phil

2

私は最終的にCompletableFuture::joinの待機をブロックするスレッドを中断します。

代わりに、私はすべての私の参加先物が終了したときに終了CompletableFutureすべてを取得するためにCompletableFuture::allofを使用しています。そして、get()メソッドをすべて Futureと呼んでください。 get()が返ってくると、私は自分の参加したすべての先物を繰り返してすべての結果を集め、getNowを呼び出します。そのような手順は中断可能です。

+0

これは[XY問題](https://meta.stackexchange.com/a/66378/167668)のように見えます... –

+0

@DidierLはい、私は、すべての先物に "参加"して結果。私はそれを明確にすべきです。 – phil

+0

'allOf()'と割り込みが実際どのように相互に関連しているかわかりません。 'allOf()'は割り込みのない問題を解決するか、割り込みが必要ですが、 'allOf()'呼び出しの結果に取り組んでいても問題はありません。 –

関連する問題