2017-05-28 37 views
3

我發現CompletableFuture ::加入似乎不間斷未完成時:如何中斷CompletableFuture :: join?

// 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()。他們基本上是相同的,除了:

  • join()來自接口CompletionStageget()自帶的接口形式Future
  • join()包裝例外CompletionExceptionget()包裝他們ExecutionException
  • get()可能被打斷,然後將引發InterruptedException

請注意,您中斷的是Thread,而不是Future。例如,下面的代碼中斷主線程在等待上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(); 
} 

輸出:

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) 
    … 

如果通過join()更換get(),中斷將確實不行。

+2

謝謝您指出'join()'和'get()'之間的區別。 – phil

2

我終於放棄了中斷線程,這個線程在等待CompletableFuture::join完成。

相反,我用CompletableFuture::allof獲得CompletableFuture所有當所有我加入期貨結束其結束。然後在工作線程中調用get()方法全部未來。當get()返回時,我通過迭代所有加入的期貨並在其上調用getNow來收集我的所有結果。這樣的程序是可中斷的。

+0

看起來這是[XY問題](https://meta.stackexchange.com/a/66378/167668)然後... –

+0

@DidierL是的,我只是想要一個可中斷的方式來「加入」所有的期貨並獲得結果。我應該澄清這一點。 – phil

+0

我不明白'allOf()'和中斷在這裏是如何相互關聯的。 'allOf()'解決了沒有中斷的問題,或者你需要中斷,但是你正在處理'allOf()'調用的結果並不重要。 –

相關問題