CountDownLatch 数到零时不会停止

CountDownLatch don't stop on counting to zero

我有一个代码示例,希望打印值。正如我在 countDownLatch.countDown() 之后的 运行 方法中所想的那样;被调用的 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();
            }
        }
    }

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