CountDownLatch не останавливается на счет до нуля - PullRequest
0 голосов
/ 05 февраля 2019

У меня есть пример кода, который я ожидаю напечатать значения.Как я думаю, после в методе run after countDownLatch.countDown ();называется CountDownLatch должен достигать нуля, и основной метод должен завершаться, но это не происходит.Я что-то упустил?

public class ExecutorWithCountDownLatch {

        public static void main(String[] args) throws InterruptedException {

            final ExecutorService executorService = Executors.newSingleThreadExecutor();
            final CountDownLatch countDownLatch = new CountDownLatch(1);
            executorService.execute(new ThreadCounter(countDownLatch));
            countDownLatch.await(5, TimeUnit.SECONDS);
        }


        private static class ThreadCounter implements Runnable {
            private CountDownLatch countDownLatch;

            public ThreadCounter(CountDownLatch countDownLatch) {
                this.countDownLatch = countDownLatch;
            }

            @Override
            public void run() {
                for (int i = 0; i <= 25; i++) {
                    System.out.println("printing numbers: " + i);
                }
                countDownLatch.countDown();
            }
        }
    }

1 Ответ

0 голосов
/ 05 февраля 2019

Вам необходимо завершить работу ExecutorService после завершения работы.

/**
 * Initiates an orderly shutdown in which previously submitted
 * tasks are executed, but no new tasks will be accepted.
 * Invocation has no additional effect if already shut down.
 *
 * <p>This method does not wait for previously submitted tasks to
 * complete execution.  Use {@link #awaitTermination awaitTermination}
 * to do that.
 *
 * @throws SecurityException if a security manager exists and
 *         shutting down this ExecutorService may manipulate
 *         threads that the caller is not permitted to modify
 *         because it does not hold {@link
 *         java.lang.RuntimePermission}{@code ("modifyThread")},
 *         or the security manager's {@code checkAccess} method
 *         denies access.
 */
void shutdown();

Таким образом, метод main будет выглядеть следующим образом:

public static void main(String[] args) throws InterruptedException {

    final ExecutorService executorService = Executors.newSingleThreadExecutor();
    final CountDownLatch countDownLatch = new CountDownLatch(1);
    executorService.execute(new ThreadCounter(countDownLatch));
    countDownLatch.await(5, TimeUnit.SECONDS);

    executorService.shutdown();
} 

Чтобы принудительно завершить работу, используйте ExecutorService.shutdownNow();:

/**
 * Attempts to stop all actively executing tasks, halts the
 * processing of waiting tasks, and returns a list of the tasks
 * that were awaiting execution.
 *
 * <p>This method does not wait for actively executing tasks to
 * terminate.  Use {@link #awaitTermination awaitTermination} to
 * do that.
 *
 * <p>There are no guarantees beyond best-effort attempts to stop
 * processing actively executing tasks.  For example, typical
 * implementations will cancel via {@link Thread#interrupt}, so any
 * task that fails to respond to interrupts may never terminate.
 *
 * @return list of tasks that never commenced execution
 * @throws SecurityException if a security manager exists and
 *         shutting down this ExecutorService may manipulate
 *         threads that the caller is not permitted to modify
 *         because it does not hold {@link
 *         java.lang.RuntimePermission}{@code ("modifyThread")},
 *         or the security manager's {@code checkAccess} method
 *         denies access.
 */
List<Runnable> shutdownNow();
...