Why CompletableFuture 's thenAccept() not running on the main thread

*爱你&永不变心* 提交于 2019-12-23 15:10:52

问题


I process the long running operation inside the CompletableFuture's supplyAsync() and get the result into thenAccept(). In some times thenAccept() perform on the main thread but some time it running on the worker thread.But I want run thenAccept() operation only on the main thread. this is the sample code.

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();
    }
}

result is :

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

How can i fix this ?


回答1:


Take a look in the JavaDoc of CompletableFuture. The interesting part is the one about the CompletionStage policies.

There you find that using the non-async method results in a kind of either-or-scenario. If you then take a look in the implementation you will end up in the non-public part of the Java Runtime. There is some UNSAFE handling that implies that there may happen some kind of race condition.

I would suggest using thenAcceptAsync() and thenRunAsync() variants and pass your executorService variable to both calls.



来源:https://stackoverflow.com/questions/36981432/why-completablefuture-s-thenaccept-not-running-on-the-main-thread

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!