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