CountDownLatch&CyclicBarrier

Catalogue
  1. 1. CountDownLatch原理
  2. 2. CyclicBarrier
  3. 3. CyclicBarrier和CountDownLatch区别
  4. 4. Semaphore

CountDownLatch的作用是使得一个或多个线程等待直到其他线程完成操作。

CyclicBarrier的作用是可以让一组线程达到一个屏障时被阻塞,直到最后一个线程达到屏障时,所有被阻塞的线程才能继续执行。

实际场景:多线程去后台查数据,需要所有数据全部获取到后再处理。

CountDownLatch原理

还是利用AQS来实现,其对外暴露的三个重要方法为。

  • CountDownLatch(int) 其实就是设置sync的state。这个值表示countDown方法需要被调用多少次调用await的方法才会被唤醒。
  • await,调用的是sync.acquireSharedInterruptibly(1); 调用该方法的线程会阻塞到state为0
  • countDown,调用的是sync.releaseShared(1); 调用该方法state计数减1

原理很简单。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 阻塞到state为0
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;
// 计数减1
int nextc = c-1;
if (compareAndSetState(c, nextc))
return nextc == 0;
}
}

CyclicBarrier

一个高级队构造函数:CyclicBarrier(int parties, Runnable barrierAction),barrierAction任务会在所有线程到达屏障后执行。

CyclicBarrierCountDownLatch区别

CountDownLatch的计数器只能使用一次,CyclicBarrier可以用reset`方法将计数器重置。因此CyclicBarrier可以处理更加复杂的业务场景。CountDownLatch一般用于某些线程等待若干个其他线程执行完任务之后,它才执行;而CyclicBarrier一般用于一组线程互相等待至某个状态,然后这一组线程再同时执行;

Semaphore

Semaphore可以用来控制同时访问特定资源的线程数量。实现比较简单,可参看Semaphore