并发编程-CountDownLatch同步计数器
2020-12-01 本文已影响0人
迦叶_金色的人生_荣耀而又辉煌
上一篇 <<<Condition
下一篇 >>>Semaphore信号量
CountDownLatch是一种java.util.concurrent包下一个同步工具类,它允许一个或多个线程等待直到在其他线程中一组操作执行完成。
和join方法非常类似CountDownLatch底层是基于AQS实现的
工作原理
CountDownLatch countDownLatch=new CountDownLatch(2) AQS的state状态为2。
调用countDownLatch.countDown();方法的时候状态-1 当AQS状态state为0的情况下,则唤醒正在等待的线程。
- 计数器---CountDownLatch
- new CountDownLatch(2) 需要等待的线程执行数
- countDownLatch.countDown(); 子线程已执行完毕
- countDownLatch.await() 等待所有线程执行完毕后执行后续的操作
CountDownLatch与Join的区别
Join底层是基于wait方法实现
CountDownLatch底层是基于AQS实现。
基于AQS手写CountDownLatch核心代码
思路
a、初始化AQS里的state
b、重写AQS里的 tryAcquireShared和tryReleaseShared方法达到线程的阻塞和唤醒操作
/**
* 构造函数设置aqs的state
* @param count state值
*/
public MyCountDownLatch(int count){
// state不允许小于0
if (count < 0) {
throw new IllegalArgumentException("count < 0");
}
sync = new Sync(count);
}
/**
* 重写阻塞的条件,当state不为零则阻塞
* @param acquires
* @return
*/
@Override
protected int tryAcquireShared(int acquires) {
return (getState() == 0) ? 1 : -1;
}
/**
* 使用自旋机制,当getState()-1后为0即唤醒
* @param releases 步长,正常情况均为1
* @return
*/
@Override
protected boolean tryReleaseShared(int releases) {
// 使用自旋
for (;;) {
int c = getState();
//当state传入的参数为0时,则直接返回不用释放锁
if (c == 0) {
return false;
}
// 执行完后state会减少
int nextc = c-releases;
// 利用CAS无锁机制,判断如果state-1为0,则唤醒其他线程
if (compareAndSetState(c, nextc)) {
return nextc == 0;
}
}
}
相关文章链接:
多线程基础
线程安全与解决方案
锁的深入化
锁的优化
Java内存模型(JMM)
Volatile解决JMM的可见性问题
Volatile的伪共享和重排序
CAS无锁模式及ABA问题
Synchronized锁
Lock锁
AQS同步器
Condition
Semaphore信号量
CyclicBarrier屏障
线程池
并发队列
Callable与Future模式
Fork/Join框架
Threadlocal
Disruptor框架
如何优化多线程总结