How to use CompletableFuture in java 8 to start an async task and let main thread finish and exit

醉酒当歌 提交于 2019-12-13 00:36:28

问题


I have the following code (more or less):

ExecutorService executor = Executors.newFixedThreadPool(10);
CompletableFuture
    .supplyAsync(()->{
        return longRunningMethodThatReturnsBoolean();
    }, executor)
    .thenAcceptAsync(taskResult -> {
        logResult();
        executor.shutdown(); 
    }, executor);

This allows the code in the main thread to continue, however I was expecting the main thread to die when it finished and the future to keep working in it's own thread, but the main thread stays alive until the CompletableFuture finishes even though the main thread isn't doing anything anymore.

I'm kind of new to this, am I missing something? Is it even possible?

Any help will be greatly appreciated!!!


回答1:


Actually, if your main thread doesn't wait on the CompletableFuture's .get() or any other blocking method, then it dies as soon as it reaches the end of the main method.

You can check it using the following example:

public static void main(String[] args){
    final Thread mainThread = Thread.currentThread();
    ExecutorService executor = Executors.newFixedThreadPool(10);
    CompletableFuture
            .supplyAsync(()-> {
                try {
                    Thread.sleep(1000);
                    //prints false
                    System.out.println("Main thread is alive: " + mainThread.isAlive());
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return true;
            }, executor)
            .thenAcceptAsync(taskResult -> {
                System.out.println("LongRunning is finished");
                executor.shutdown();
            }, executor);
}

But the Java Virtual Machine continues to execute threads until either of the following occurs

  • The exit method of class Runtime has been called and the security manager has permitted the exit operation to take place.
  • All threads that are not daemon threads have died, either by returning from the call to the run method or by throwing an exception that propagates beyond the run method.

It means that even though the main thread is dead, the virtual machine continues to work because all threads created by the Executors.newFixedThreadPool(10) are non-daemon. You can read about it in the documentation of the defaultThreadFactory() method in the Executors class:

Each new thread is created as a non-daemon thread with priority set to the smaller of Thread.NORM_PRIORITY and the maximum priority permitted in the thread group




回答2:


The main thread waits until all the other non-daemon threads are done before cleaning up and exiting the process:

http://hg.openjdk.java.net/jdk7/jdk7/hotspot/file/9b0ca45cd756/src/share/vm/runtime/thread.cpp#l3629



来源:https://stackoverflow.com/questions/48573856/how-to-use-completablefuture-in-java-8-to-start-an-async-task-and-let-main-threa

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