0

I have a sample of code which I expect to print values. As I think after in run method after countDownLatch.countDown(); is called CountDownLatch should reach zero and main method should terminate, but it's not happening. Am I missing something?

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();
            }
        }
    }
pablosaraiva
  • 2,343
  • 1
  • 27
  • 38
Artem Vlasenko
  • 115
  • 1
  • 1
  • 7

1 Answers1

6

You need to shutdown ExecutorService after your jobs are finished.

/**
 * 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();

So the main method will look like this:

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();
} 

To force the shutdown, use 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();
J-Alex
  • 6,881
  • 10
  • 46
  • 64