我在CompletableFuture的supplyAsync()中處理長時間運行的操作,並將結果導入到thenAccept()中。在某些時候,接受()在主線程上執行,但有一段時間它在工作線程上運行。但是我想僅在主線程上運行thenAccept()操作。這是示例代碼。爲什麼CompletableFuture的thenAccept()未在主線程上運行
private void test() {
ExecutorService executorService = Executors.newSingleThreadExecutor();
CompletableFuture<String> cf1 = CompletableFuture.supplyAsync(() -> {
System.out.println("supplyAsync | I am running on : " + Thread.currentThread().getName());
return "Hello world";
}, executorService);
CompletableFuture<Void> cf3 = cf1.thenAccept(s -> {
System.out.print("thenAccept | I am running on : " + Thread.currentThread().getName());
System.out.println(" | answer : " + s);
});
cf3.thenRun(() -> {
System.out.println("thenRun | I am running on : " + Thread.currentThread().getName());
System.out.println();
});
}
public static void main(String[] args) {
App app = new App();
for(int i = 0; i < 3; i++){
app.test();
}
}
結果是:
supplyAsync | I am running on : pool-1-thread-1
thenAccept | I am running on : main | answer : Hello world
thenRun | I am running on : main
supplyAsync | I am running on : pool-2-thread-1
thenAccept | I am running on : main | answer : Hello world
thenRun | I am running on : main
supplyAsync | I am running on : pool-3-thread-1
thenAccept | I am running on : pool-3-thread-1 | answer : Hello world
thenRun | I am running on : pool-3-thread-1
我怎樣才能解決這個問題?
你爲什麼想這樣做? – sisyphus
謝謝。假設我在訪問共享資源的方法中使用了thenAccept()方法。然後我必須考慮資源的線程安全性。 Vert.x的executeBlocking與此類似。他們正確處理這一點。 – Tharanga
那麼,'正確'可能在旁觀者的眼中。如果您以異步方式訪問共享資源,您似乎需要關注線程安全性。也許你應該只允許通過監視器訪問共享資源,該監視器在單個線程上調度任務。 – sisyphus