該complete
調用觸發所有依賴CompletionStage
s。
因此,如果您之前註冊了BiConsumer
和whenComplete
,complete
將在其調用線程中調用它。在你的情況下,當BiConsumer
傳遞給whenComplete
時,complete
的呼叫將返回。這在對非異步方法依賴完井可以 通過即完成當前 CompletableFuture
,或通過完成方法的任何其他呼叫者線程執行供給的所述class javadoc
操作說明。
(由另一呼叫者是相反的情況,即線程調用whenComplete
實際上應用BiConsumer
如果目標CompletableFuture
已經完成。)
這裏有一個小程序來說明行爲:
public static void main(String[] args) throws Exception {
CompletableFuture<String> future = new CompletableFuture<String>();
future.whenComplete((r, t) -> {
System.out.println("before sleep, executed in thread " + Thread.currentThread());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("after sleep, executed in thread " + Thread.currentThread());
});
System.out.println(Thread.currentThread());
future.complete("completed");
System.out.println("done");
}
這將打印
Thread[main,5,main]
before sleep, executed in thread Thread[main,5,main]
after sleep, executed in thread Thread[main,5,main]
done
顯示在主線程中應用了BiConsumer
,這個主線程叫做complete
。
您可以使用whenCompleteAsync
強制在單獨的線程中執行BiConsumer
。
[...]執行時,這個階段完成使用此階段的默認 異步執行機構指定的動作。
例如,
public static void main(String[] args) throws Exception {
CompletableFuture<String> future = new CompletableFuture<String>();
CompletableFuture<?> done = future.whenCompleteAsync((r, t) -> {
System.out.println("before sleep, executed in thread " + Thread.currentThread());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("after sleep, executed in thread " + Thread.currentThread());
});
System.out.println(Thread.currentThread());
future.complete("completed");
System.out.println("done");
done.get();
}
將打印
Thread[main,5,main]
done
before sleep, executed in thread Thread[ForkJoinPool.commonPool-worker-1,5,main]
after sleep, executed in thread Thread[ForkJoinPool.commonPool-worker-1,5,main]
表明該BiConsumer
在單獨的線程施加。
非常感謝。你的解釋非常清楚線程。 在我第一次使用CompletableFuture時,我只使用它來調用從客戶端到服務器的單個請求(如SELECT,UPDATE等),所以它完全按照我的期望(客戶端等待響應並填補未來)運行。 但是現在,我在做TRANSACTION時遇到問題,因爲它有階段。我希望在所有SELECT完成後立即作爲CompletableFuture返回未來,但只有在其他執行(UPDATE,DELETE)有結果時才填充未來。 你能建議我一個解決方案來處理鏈中的事情嗎? 非常感謝! –
我想按以下順序做事: 1. SELECT - > CompletableFuture 2. PREPARE - > CompletableFuture(其他的調用也會返回CompletableFutures)。 3. COMMIT - > CompletableFuture 並且當我註冊它時,事務必須立即返回給調用者。 非常感謝! –