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