Основной поток завершается до завершения CompletableFuture - PullRequest
1 голос
/ 20 марта 2019
    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";
    }

Сначала я вызываю метод compose из supplyAsync, где я выполняю метод composeMethod, с задержкой в ​​три миллисекунды, а затем он создает файл и возвращает в качестве результата строку. после его завершения я вызываю метод thenRun, который просто печатает метод, после чего существует метод неблокирования, который запускается из основного потока.

проблема, с которой я здесь сталкиваюсь, заключается в том, что основной поток завершает выполнение nonblockingmethod () и выходит из процесса до задержки в 3 миллисекунды во время последующей операции из composeMethod. это ожидаемое поведение, или мне нужно заблокировать основной поток, используя get или join, или я что-то пропустил

1 Ответ

3 голосов
/ 20 марта 2019

Ваша задача, указанная в 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"));

Вывод:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...