并发编程(1)-java中的6中线程状态
并发编程(2)-怎么中断线程?
并发编程(3)-synchronized的实现原理
并发编程(4)-深入理解volatile关键字
并发编程(5)-ReentrantLock源码分析
并发编程(6)-Condition源码分析
并发编程(7)-juc阻塞队列介绍
并发编程(8)-什么是异步责任链
并发编程(9)-Semaphore介绍和源码分析
一、 CyclicBarrier的使用
public class CyclicBarrierDemo {
static class RunTask implements Runnable {
private CyclicBarrier cyclicBarrier;
public RunTask(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
System.out.println("线程准备好了"+Thread.currentThread().getName());
try {
Thread.sleep(2000);
cyclicBarrier.await();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("开始冲!"+Thread.currentThread().getName());
}
}
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
Thread t1 = new Thread(new RunTask(cyclicBarrier));
Thread t2 = new Thread(new RunTask(cyclicBarrier));
Thread t3 = new Thread(new RunTask(cyclicBarrier));
t1.start();
t2.start();
t3.start();
}
}
new CyclicBarrier(3)初始化为3,当调用**cyclicBarrier.await()**时,就会减1,如果当前等于0,则当前线程则色。当减到0以后,将唤醒起所有阻塞的线程。
二、源码分析
cyclicBarrier.await()
private int dowait(boolean timed, long nanos)
throws InterruptedException, BrokenBarrierException,
TimeoutException {
// 获取到锁
final ReentrantLock lock = this.lock;
lock.lock();
try {
final Generation g = generation;
if (g.broken)
throw new BrokenBarrierException();
if (Thread.interrupted()) {
breakBarrier();
throw new InterruptedException();
}
// 数字递减
int index = --count;
if (index == 0) { // tripped
boolean ranAction = false;
try {
final Runnable command = barrierCommand;
if (command != null)
command.run();
ranAction = true;
// 等于0是将唤醒同步队列里面的所有线程
nextGeneration();
return 0;
} finally {
if (!ranAction)
breakBarrier();
}
}
// loop until tripped, broken, interrupted, or timed out
for (;;) {
try {
if (!timed)
// 不为0 则阻塞
trip.await();
else if (nanos > 0L)
nanos = trip.awaitNanos(nanos);
} catch (InterruptedException ie) {
if (g == generation && ! g.broken) {
breakBarrier();
throw ie;
} else {
// We're about to finish waiting even if we had not
// been interrupted, so this interrupt is deemed to
// "belong" to subsequent execution.
Thread.currentThread().interrupt();
}
}
if (g.broken)
throw new BrokenBarrierException();
if (g != generation)
return index;
if (timed && nanos <= 0L) {
breakBarrier();
throw new TimeoutException();
}
}
} finally {
lock.unlock();
}
}