CountDownLatch不会停止计数到零

时间:2019-02-05 14:15:02

标签: java multithreading countdownlatch

我有一个示例代码,希望可以打印出值。我认为在countDownLatch.countDown()之后的run方法中;被称为CountDownLatch应该达到零并且main方法应该终止,但是这没有发生。我想念什么吗?

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 :(得分:4)

作业完成后,您需要关闭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();