主线程在 CompletableFuture 完成之前退出

jav*_*rld 3 java multithreading asynchronous

    CompletableFuture feature = CompletableFuture.supplyAsync (() ->       composeMethod ( )).
            thenAccept (s -> System.out.println ("wassup java" + s)).
            thenRun (() -> System.out.println (" imm immortal"));
    nonblockingmethod ( );
Run Code Online (Sandbox Code Playgroud)

这是我正在研究的 CompletableFuture 未来示例

private static void nonblockingmethod() {
        System.out.println ("why  should i wait for you ");
    }

    private static String composeMethod() {
        try {
            TimeUnit.MILLISECONDS.sleep (3);
            File file = Paths.get ("/Users/solo/solo1.txt").toFile ( );

            if (!file.exists ( )) {
                file.createNewFile ( );
            }

        } catch (Exception e) {

        }
        return "   resultdaa";
    }
Run Code Online (Sandbox Code Playgroud)

首先我从 SupplyAsync 调用 compose 方法,在其中执行方法 composeMethod ,有三毫秒的延迟,然后它将创建一个文件并返回一个字符串作为结果。完成后我调用 thenRun 方法,该方法仅打印一个方法,之后有一个从主线程运行的非阻塞方法。

我在这里面临的问题是主线程完成执行nonblockingmethod()并在3毫秒延迟之前退出进程,同时来自composeMethod的后续操作。这是预期的行为还是我必须使用 get 或 join 阻止主线程,或者我错过了任何东西

Ami*_*era 7

您在 中提供的任务supplyAsync将在 中执行ForkJoinPool#commonPool。如果你看一下 中的线程,common pool你会发现它们是Deamon thread,这意味着 JVM 不会等待关闭该守护线程来完成其执行。在active non-daemon thread你的情况下,你有一个睡眠composeMethod和在同时,主线程执行并完成其工作,因此JVM does not have any active non-daemon thread,JVM 将直接进入,而shut down无需等待您的任务完成。如果运行下面的示例,您可以确认线程池和线程类型。

CompletableFuture feature = CompletableFuture.supplyAsync(() -> {
    System.out.println("Thread : " + Thread.currentThread());
    System.out.println("Is Daemon : " + Thread.currentThread().isDaemon());
    return composeMethod();
}).thenAccept(s -> System.out.println("wassup java" + s)).thenRun(() -> System.out.println(" imm immortal"));
Run Code Online (Sandbox Code Playgroud)

输出:

Thread : Thread[ForkJoinPool.commonPool-worker-1,5,main] // This line may be bit different but it indicates that your task is executing on Common pool
Is Daemon : true
why  should i wait for you 
Run Code Online (Sandbox Code Playgroud)

要解决该问题,您可以传递自己的执行器,如下所示:

ExecutorService executorService = Executors.newFixedThreadPool(8);
CompletableFuture feature = CompletableFuture.supplyAsync(() -> {
        System.out.println("Thread : " + Thread.currentThread());
        System.out.println("Is Daemon : " + Thread.currentThread().isDaemon());
        return composeMethod();
    }, executorService).thenAccept(s -> System.out.println("wassup java" + s))
            .thenRun(() -> System.out.println(" imm immortal"));
executorService.shutdown();
nonblockingmethod();
Run Code Online (Sandbox Code Playgroud)

输出:

Thread : Thread[pool-1-thread-1,5,main]
Is Daemon : false
why  should i wait for you 
wassup java   resultdaa
 imm immortal
Run Code Online (Sandbox Code Playgroud)