主线程在CompletableFuture完成之前退出

时间:2019-03-20 18:04:13

标签: java multithreading asynchronous

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

这是正在处理的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";
    }

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

我在这里面临的问题是主线程完成执行nonblockingmethod()并在3毫秒延迟之前退出进程,而随后的操作是composeMethod。这是预期的行为,还是我必须使用get或join阻止主线程,或者我什么都错过了

1 个答案:

答案 0 :(得分:3)

您在supplyAsync中提供的任务将在ForkJoinPool#commonPool中执行。而且,如果您查看common pool中的线程,您会发现它们是 Deamon thread ,这意味着JVM不会等待Shutdown来完成该守护进程线程的操作。在没有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"));

输出:

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 
  

要解决此问题,您可以像下面这样通过您自己的执行程序:

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

输出:

Thread : Thread[pool-1-thread-1,5,main]
Is Daemon : false
why  should i wait for you 
wassup java   resultdaa
 imm immortal