我在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