Learn java thread communication with me 3:CountDownLatch
1. Introduction
This post would demo how to do the thread communication by using CountDownLatch. If you want to know the wait-notify communication, you can refer to the previous article, if you want to learn how to communicate through the volatile keyword, you can refer to this article
1. Environments
- Java 1.8
2.1 The CountDownLatch introduction
By using CountDownLatch , you can block the main thread to wait for all children threads done.
As this picture shows:
- Main thread construct a CountDownLatch(3) and starts all children threads
- Main thread calls the latch.await() to wait for all children thread done
- Thread 1/2/3 done at different time(They call latch.countDown())
- Main thread resumed when the latch count changes to 0
2.2 The CountDownLatch classic example
Here is an example of the CountDownLatch classic usage:
CountDownLatch classic usage scenarioes:
Achieving Maximum Parallelism : Sometimes we want to start a number of threads at the same time to achieve maximum parallelism. For example, we want to test a class for being singleton. This can be done easily if we create a CountDownLatch with initial count 1, and make wait all threads to wait of latch. A single call to countDown() method will resume execution for all waiting threads in same time.
Wait N threads to completes before start execution: For example an application start-up class want to ensure that all N external systems are Up and running before handling the user requests.
Deadlock detection: A very handy use case in which you can use N threads to access a shared resource with different number of threads in each test phase, and try to create a deadlock.
Run the above code ,we got this result:
You can see that main thread resumed after all threads done.
2.3 CountDownLatch with ExecutorService(ThreadPool) example
What if we put the worker thread in a pool, here is the code:
As the code shows:
- We create a fixed size thread pool via Executors class and submit the worker threads to it
- We call latch.await() to wait for threads done
- The worker thread just sleep for a while and then call latch.countDown()
- When latch.getCount()=0, the main thread resumed
- We call pool.shutdown() to close the pool, otherwise, because all thread in the ThreadPool is not daemon, so the main thread would not exit automatically
- After we print the all workers in pool stopped message, main thread exited ok
Here is the output:
2.4 CountDownLatch with the await timeout settings example
There is a overloaded version of await method in the CountDownLatch which support to wait for limited time period, after that time, it would resume ignoring the latch status.
await(long timeout, TimeUnit unit) Causes the current thread to wait until the latch has counted down to zero, unless the thread is interrupted, or the specified waiting time elapses.
Here is the example code:
- line 1: The latch wait for at max 2 seconds,after 2 seconds, if there still exists some thread not completed, it would just abort and resume the main thread
- Attention: No exception would be thrown if the timeout occurs
Here is the output:
As you can see, only worker0 completed before timeout, the main thread resumed and stopped immediately after the timeout.
3. Summary
The CountDownlatch is very easy to use, however, it has shortcomings: The disadvantage of CountDownLatch is that it’s not reusable: once the count become zero it is no longer usable.
You can find the whole code examples on github project, the class source code is located at this, they are named like ThreadComm3_*.java
You can find detail documents about the java stream here: