正如每个Java文档所描述的那样,CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行。
CountDownLatch是在java1.5被引入的,跟它一起被引入的并发工具类还有CyclicBarrier、Semaphore、ConcurrentHashMap和BlockingQueue,它们都存在于java.util.concurrent包下。CountDownLatch这个类能够使一个线程等待其他线程完成各自的工作后再执行。例如,应用程序的主线程希望在负责启动框架服务的线程已经启动所有的框架服务之后再执行。
CountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就会减1。当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务。
package main.java.study;
import java.text.SimpleDateFormat; import java.util.Date; import java.util.concurrent.CountDownLatch;
public class CountDownLatchTest {
public class MapOper implements Runnable { CountDownLatch latch ;
public MapOper(CountDownLatch latch) { this.latch = latch; }
public void run() { try { SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println(Thread.currentThread().getName() + "start:" + df.format(new Date())); latch.await(); System.out.println(Thread.currentThread().getName() + "work:" + df.format(new Date())); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+" Sync Started!"); } }
public static void main(String[] args) throws InterruptedException { // TODO Auto-generated method stub CountDownLatchTest test = new CountDownLatchTest(); CountDownLatch latch = new CountDownLatch(1); Thread t1 = new Thread(test.new MapOper(latch)); Thread t2 = new Thread(test.new MapOper(latch)); Thread t3 = new Thread(test.new MapOper(latch)); Thread t4 = new Thread(test.new MapOper(latch)); t1.setName("Thread1"); t2.setName("Thread2"); t3.setName("Thread3"); t4.setName("Thread4"); t1.start(); Thread.sleep(1500); t2.start(); Thread.sleep(1500); t3.start(); Thread.sleep(1500); t4.start(); System.out.println("thread already start, sleep for a while..."); Thread.sleep(1000); latch.countDown();
}
}
执行结果:线程在不同时刻启动,但是等待后在同一时刻工作。
Thread1start:2019-05-25 13:24:01 Thread2start:2019-05-25 13:24:02 Thread3start:2019-05-25 13:24:04 thread already start, sleep for a while... Thread4start:2019-05-25 13:24:05 Thread1work:2019-05-25 13:24:06 Thread1 Sync Started! Thread2work:2019-05-25 13:24:06 Thread2 Sync Started! Thread3work:2019-05-25 13:24:06 Thread3 Sync Started! Thread4work:2019-05-25 13:24:06 Thread4 Sync Started!
调用countDownLatch.await()方法的线程,它会处于挂起状态,直到所有的线程都执行完countDownLatch.countDown方法,最终将计数器减为0,才会被唤醒继续执行。
AbstractQueuedSynchronizer相关源码参考:https://blog.csdn.net/demon7552003/article/details/90105335
