CompletableFutureのsupplyAsync()内で長時間実行される操作を処理し、thenAccept()に結果を取得します。いくつかの時間で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