JUC代码浅析[5]——基于AQS的CountDownLatch
JUC代码浅析[5]——基于AQS的CountDownLatch
CountDownLatch是一种使线程等待一组其他线程操作完成再开始的同步方式,初始化时设置一个计数值,每完成一次操作后countDown()对计数值减操作,线程等待await()直到计数值为0。
为了说明使用场景拷贝了代码注释中的例子,
class Driver { // ...
void main() throws InterruptedException {
CountDownLatch startSignal = new CountDownLatch(1);
CountDownLatch doneSignal = new CountDownLatch(N);
for (int i = 0; i < N; ++i) // create and start threads
new Thread(new Worker(startSignal, doneSignal)).start();
doSomethingElse();
startSignal.countDown(); // 所有的worker线程开始
doSomethingElse();
doneSignal.await(); // 等待doneSignal计数值为0
}
}
class Worker implements Runnable {
private final CountDownLatch startSignal;
private final CountDownLatch doneSignal;
Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
this.startSignal = startSignal;
this.doneSignal = doneSignal;
}
public void run() {
try {
startSignal.await();//等待主线程把startSignal计数值减到0(countDown)
doWork();
doneSignal.countDown();//把doneSignal的计数值剪1
} catch (InterruptedException ex) {} // return;
}
void doWork() { ... }
}
在理解AQS的基础上,分析CountDownLatch是比较简单的,它是基于共享模式的实现。下面是await()方法的实现
public void await() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
最终会调用sync的tryAcquireShared方法判断是否可以获得锁,下面的代码说明了state等于0时就可以获得锁,await也就将执行结束,线程就可以往下继续执行了
public int tryAcquireShared(int acquires) {
return getState() == 0? 1 : -1;
}
再看countDown方法,
public void countDown() {
sync.releaseShared(1);
}
最终会通过sync的tryReleaseShared来尝试释放锁,就是通过CAS操作来减少计数
public 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;
}
}
上一篇: 微信提醒:这些都是外挂软件 大家不要用
下一篇: jdk8新增 optional 用法
推荐阅读
-
JUC代码浅析[3]——基于AQS的锁ReentrantReadWriteLock
-
JUC代码浅析[4]——基于AQS的信号量Semaphore
-
JUC代码浅析[2]——基于AQS的锁ReentrantLock
-
JUC代码浅析[4]——基于AQS的信号量Semaphore
-
JUC代码浅析[6]——基于AQS的CyclicBarrier
-
JUC代码浅析[2]——基于AQS的锁ReentrantLock
-
JUC代码浅析[5]——基于AQS的CountDownLatch
-
JUC代码浅析[3]——基于AQS的锁ReentrantReadWriteLock
-
JUC代码浅析[6]——基于AQS的CyclicBarrier