Recently, I noticed that this category is asked a lot in the interview, so take notes. Think the bottom of this write good, so copied over, for the follow-up to watch learning
1. The background
- CountDownLatch was introduced in java1.5, along with CyclicBarrier, Semaphore, concurrentHashMap, and BlockingQueue.
- It exists under the java.util.cucurrent package.
Concept 2.
- The countDownLatch class causes a thread to wait for other threads to complete their own execution.
- This is done with a counter whose initial value is the number of threads. Each time a thread completes, the counter has a value of -1. When the counter has a value of 0, it indicates that all threads have completed, and the threads waiting on the lock can resume work.
3. The source code
- CountDownLatch provides a constructor
// The argument count is the count value
public CountDownLatch(int count) {};Copy the code
- There are three methods in the class that are most important
// The thread calling the await() method is suspended and waits until count is 0 before continuing
public void await(a) throws InterruptedException {};// Similar to await(), except to wait a certain amount of time before count has changed to 0
public boolean await(long timeout, TimeUnit unit) throws InterruptedException {};// Subtract count by 1
public void countDown(a) {};Copy the code
Example 4.
Common example:
public class CountDownLatchTest {
public static void main(String[] args) {
final CountDownLatch latch = new CountDownLatch(2);
System.out.println("The main thread starts executing... ...");
// The first child thread executes
ExecutorService es1 = Executors.newSingleThreadExecutor();
es1.execute(new Runnable() {
@Override
public void run(a) {
try {
Thread.sleep(3000);
System.out.println("Child thread:"+Thread.currentThread().getName()+"Performing");
} catch(InterruptedException e) { e.printStackTrace(); } latch.countDown(); }}); es1.shutdown();// The second child thread executes
ExecutorService es2 = Executors.newSingleThreadExecutor();
es2.execute(new Runnable() {
@Override
public void run(a) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Child thread:"+Thread.currentThread().getName()+"Performing"); latch.countDown(); }}); es2.shutdown(); System.out.println("Wait for two threads to complete... ...");
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Both child threads are finished, continue to execute the main thread."); }}Copy the code
The result set
The main thread starts executing... ... Wait for two threads to finish executing...... ... Child thread: pool-1-thread-1 Execution child thread: pool-2-thread-1 Execution When the two child threads finish executing, the main thread continues to executeCopy the code
Simulating concurrent examples
public class Parallellimit {
public static void main(String[] args) {
ExecutorService pool = Executors.newCachedThreadPool();
CountDownLatch cdl = new CountDownLatch(100);
for (int i = 0; i < 100; i++) {
CountRunnable runnable = newCountRunnable(cdl); pool.execute(runnable); }}}class CountRunnable implements Runnable {
private CountDownLatch countDownLatch;
public CountRunnable(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
@Override
public void run(a) {
try {
synchronized (countDownLatch) {
/*** reduce the capacity one at a time */
countDownLatch.countDown();
System.out.println("thread counts = " + (countDownLatch.getCount()));
}
countDownLatch.await();
System.out.println("concurrency counts = " + (100 - countDownLatch.getCount()));
} catch(InterruptedException e) { e.printStackTrace(); }}}Copy the code
The difference between CountDownLatch and CyclicBarrier:
- 1. CountDownLatch is a counter that can only be used once when the thread completes each record
- 2. The CyclicBarrier counter is more like a valve that requires all threads to arrive and continue executing, incrementing the counter and providing a reset function that can be used multiple times