CountDownLatch是Java提供的线程递减锁,为开发人员封装出来针对特殊场景使用的工具类,主要用在某一个动作的执行以来其他动作对应线程的完成。
使用步骤:
1.拿到一个CountDownLatch实例,初始化大小为依赖的动作线程数
2.将CountDownLatch实例传递给依赖线程
3.在依赖线程执行完对应的动作后调用CountDownLatch.countDown方法
4.在主线程中调用CountDownLatch.await方法
package com.jv.parallel.feature;import java.util.concurrent.CountDownLatch;/* * 线程递减锁,用来控制某一个动作的执行依赖其他动作线程的完成 * * 例如:开始钓鱼之前先要做主线、拌饵料、打窝子 */public class TestCountDownLatch { public static void main(String[] args) throws InterruptedException { // 1.声明一个线程递减锁 // 因为在钓鱼 CountDownLatch cdl = new CountDownLatch(3); new Thread(new TieLine(cdl)).start(); new Thread(new MixedFood(cdl)).start(); new Thread(new Feed(cdl)).start(); cdl.await(); System.out.println("开始愉快的钓鱼了"); } /* * 制作钓鱼的主线 */ static class TieLine implements Runnable{ CountDownLatch cdl; public TieLine(CountDownLatch cdl) { this.cdl = cdl; } @Override public void run() { System.out.println("制作4.5的主线"); cdl.countDown(); } } /* * 拌饵料 */ static class MixedFood implements Runnable{ CountDownLatch cdl; public MixedFood(CountDownLatch cdl) { this.cdl = cdl; } @Override public void run() { System.out.println("拌饵料"); cdl.countDown(); } } /* * 做窝子 */ static class Feed implements Runnable{ CountDownLatch cdl; public Feed(CountDownLatch cdl) { this.cdl = cdl; } @Override public void run() { System.out.println("打窝子"); cdl.countDown(); } }}
CountDownLatch核心是使用了一个继承AbstractQueuedSynchronizer的同步器,这种设计模式称之为模板方法(在抽象类中定义算法的骨架,由子类实现骨架中具体的方法),模板方法设计模式可以参阅
CountDownLatch.await方法
public void await() throws InterruptedException { sync.acquireSharedInterruptibly(1); }
同步器的acquireSharedInterruptibly方法其实是CountDownLatch.Syn父类AbstractQueuedSynchronizer的,它就是一个算法骨架
public final void acquireSharedInterruptibly(int arg) throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); if (tryAcquireShared(arg) < 0) doAcquireSharedInterruptibly(arg); }
acquireSharedInterruptibly的核心就是调用子类实现的tryAcquireShared
再看CountDownLatch.Syn中实现的抽象方法tryAcquireShared,tryReleaseShared
protected int tryAcquireShared(int acquires) { return (getState() == 0) ? 1 : -1; } protected boolean tryReleaseShared(int releases) { // Decrement count; signal when transition to zero for (;;) { int c = getState(); if (c == 0) return false; int nextc = c-1; if (compareAndSetState(c, nextc)) return nextc == 0; } }
CountDownLatch.countDown方法
public void countDown() { sync.releaseShared(1); }
同步器的releaseShared方法其实是CountDownLatch.Syn父类AbstractQueuedSynchronizer的,它也是一个算法骨架
public final boolean releaseShared(int arg) { if (tryReleaseShared(arg)) { doReleaseShared(); return true; } return false; }
releaseShared的核心就是调用子类实现的tryReleaseShared