Ad

Why Don't These CompletableFuture Objects Terminate The Main Method

- 1 answer

I am trying to understand CompletableFutures. I don't understand why the program does not terminate after the main method is completed unless I call get() or join() explicitly on cf1 and cf2 each.

public class Understand {

    public static void main(String[] args) throws Exception {
        ExecutorService cpuBound = Executors.newSingleThreadExecutor();
        ExecutorService ioBound = Executors.newFixedThreadPool(3);

        for (int x = 0; x < 3; x++) {
            CompletableFuture<Void> cf1 = CompletableFuture.runAsync(() -> {
                System.out.println("cf1");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, cpuBound).thenRun(() -> System.out.println("done cf1"));

            CompletableFuture<Void> cf2 = CompletableFuture.runAsync(() -> {
                System.out.println("cf2");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, ioBound).thenRun(() -> System.out.println("done cf2"));
        }

        System.out.println("Main Thread ends");
    }
}
Ad

Answer

A Java program only exists when all non-daemon threads have ended, including the main thread. That last one ends, but your executors still have active threads. If you call shutdown() on these, you're asking them to shutdown when they are ready to do so; in other words, when all their jobs have finished.

If you add these two statements just before the last println statement your program will exit:

cpuBound.shutdown();
ioBound.shutdown();
Ad
source: stackoverflow.com
Ad