CountDownLatch 是一个同步工具类,它容许一个或多个线程一直等待,直到其余线程的操做执行完后再执行.html
CountDownLatch 是经过一个计数器来实现的,计数器的初始值为线程的数量。每当一个线程完成了本身的任务后,计数器的值就会减1。当计数器值到达0时,它表示全部的线程已经完成了任务,而后在闭锁上等待的线程就能够恢复执行任务。java
主要方法有:api
使用场景:多线程
在一些应用场景中,须要等待某个条件达到要求后才能作后面的事情;同时当线程都完成后也会触发事件,以便进行后面操做。oracle
CountDownLatch的countDown() 和 await(),前者主要倒数一次,后者是等待倒数到0,若是没有到0,就只有阻塞等待了。ide
1 public class Demo { 2 3 public static void main(String[] args) throws Exception { 4 5 CountDownLatch latch = new CountDownLatch(3); 6 Worker worker1 = new Worker("xiao ming", latch); 7 Worker worker2 = new Worker("xiao hong", latch); 8 Worker worker3 = new Worker("xiao wang", latch); 9 10 worker1.start(); 11 worker2.start(); 12 worker3.start(); 13 14 latch.await(); 15 16 System.out.println("Main Thread End."); 17 } 18 19 static class Worker extends Thread { 20 21 private String workerName; 22 private CountDownLatch latch; 23 24 public Worker(String workerName, CountDownLatch latch) { 25 26 this.workerName = workerName; 27 this.latch = latch; 28 } 29 30 @Override 31 public void run() { 32 33 try { 34 System.out.println("Worker:" + workerName + " is begin."); 35 Thread.sleep(1000L); 36 System.out.println("Worker:" + workerName + " is end."); 37 } catch (Exception e) { 38 e.printStackTrace(); 39 } 40 latch.countDown(); 41 } 42 } 43 }
输出:工具
1 Worker:xiao ming is begin. 2 Worker:xiao hong is begin. 3 Worker:xiao wang is begin. 4 Worker:xiao ming is end. 5 Worker:xiao wang is end. 6 Worker:xiao hong is end. 7 Main Thread End.
CountDownLatch 的实现原理:测试
CountDownLatch 的核心实现机制利用 AbstractQueuedSynchronizer 简称“AQS”的 state状态来实现Count的阻塞机制。ui
1 public class CountDownLattch { 2 3 /** 4 *CountDownLatch 的核心实现机制利用 AbstractQueuedSynchronizer 简称“AQS”的 state状态来实现Count的阻塞机制 5 */ 6 7 private static final class Sync extends AbstractQueuedSynchronizer { 8 9 Sync(int count) { 10 setState(count); 11 } 12 13 int getCount() { 14 return getState(); 15 } 16 17 protected int tryAcquireShared(int acquires) { 18 return (getState() == 0) ? 1 : -1; 19 } 20 21 protected boolean tryReleaseShared(int releases) { 22 // 覆盖"AQS"的释放状态方式,实现本身的逻辑,来消减count的线程数 23 for(;;) { 24 25 int c = getState(); 26 if (c == 0) 27 return false; 28 29 int nextc = c - 1; 30 if (compareAndSetState(c, nextc)) 31 return nextc == 0; 32 } 33 } 34 35 } 36 37 private final Sync sync; 38 // 利用"AQS"的state状态,来标示线程的count的数量 39 40 public CountDownLat(int count) { 41 this.sync = new Sync(count); 42 } 43 44 // 利用"AQS"得到一个共享模式下的完成状态 45 public void await() throws InterruptedException { 46 sync.acquireSharedInterruptibly(1); 47 } 48 49 // 利用"AQS"得到一个共享模式下的完成状态,超出了指定的等待时间 50 public void await(int timeout, TimeUnit unit) throws InterruptedException { 51 sync.tryAcquireSharedNanos(1, unit.toNanos(timeout)); 52 } 53 54 // 利用"AQS"在共享模式下释放状态也就是数字减一 55 public void countDown() { 56 sync.releaseShared(1); 57 } 58 59 // 调用"AQS"返回当前计数 60 public long getCount() { 61 return sync.getCount(); 62 } 63 64 ... 65 }