他的作用时使一组线程到达一个屏障点(也可以叫同步点)时会被阻塞,直到最后同一个线程到达屏障时,屏障就会开门,所以的被拦截的线程才会继续执行。

构造器

  1. public CyclicBarrier(int parties, Runnable barrierAction) {
  2. if (parties <= 0) throw new IllegalArgumentException();
  3. this.parties = parties;
  4. this.count = parties;
  5. this.barrierCommand = barrierAction;
  6. }

构造器可知CyclicBarrier创建时,会有一个阻塞线程数和一个阻塞后运行的线程。

await()同步点

  1. public int await() throws InterruptedException, BrokenBarrierException {
  2. try {
  3. return dowait(false, 0L);//nanos时等待时间
  4. } catch (TimeoutException toe) {
  5. throw new Error(toe); // cannot happen
  6. }
  7. }
  1. private int dowait(boolean timed, long nanos)
  2. throws InterruptedException, BrokenBarrierException,
  3. TimeoutException {
  4. final ReentrantLock lock = this.lock;//维护了一把重入锁
  5. lock.lock();//线程要先获取锁
  6. try {
  7. final Generation g = generation;
  8. if (g.broken)
  9. throw new BrokenBarrierException();
  10. if (Thread.interrupted()) {
  11. breakBarrier(); //破环屏障
  12. throw new InterruptedException();
  13. }
  14. int index = --count;//已经执行过到这里的次数,由于这里已经加锁所以不会有并发问题
  15. if (index == 0) { // tripped,所以的线程都到了这个屏障点
  16. boolean ranAction = false;
  17. try {
  18. final Runnable command = barrierCommand;//获取屏障CyclicBarrier构造器的线程
  19. if (command != null)
  20. command.run();//由最后一个线程调用run方法(这里没有新建一个线程)
  21. ranAction = true;
  22. nextGeneration();
  23. return 0;
  24. } finally {
  25. if (!ranAction)
  26. breakBarrier();//破环屏障
  27. }
  28. }
  29. // loop until tripped, broken, interrupted, or timed out 循环直到触发、损坏、中断 或者超时
  30. for (;;) {
  31. try {
  32. if (!timed)//不需要超时等待
  33. trip.await();//condition阻塞在这里,让其他线程抢占lock
  34. else if (nanos > 0L)
  35. nanos = trip.awaitNanos(nanos);//超时阻塞,等待被唤醒或者超时
  36. } catch (InterruptedException ie) {//阻塞时候被中断。
  37. if (g == generation && ! g.broken) {
  38. breakBarrier();//破环屏障
  39. throw ie;
  40. } else {
  41. // We're about to finish waiting even if we had not
  42. // been interrupted, so this interrupt is deemed to
  43. // "belong" to subsequent execution.
  44. Thread.currentThread().interrupt();//回复中断标识
  45. }
  46. }
  47. if (g.broken)
  48. throw new BrokenBarrierException();
  49. if (g != generation)
  50. return index;
  51. if (timed && nanos <= 0L) {
  52. breakBarrier();
  53. throw new TimeoutException();
  54. }
  55. }
  56. } finally {
  57. lock.unlock();
  58. }
  59. }

可以看出,运行到cyclicbarrier.await()方法后会维护一把重入锁,每个线程进来计算器-1,并通过condition阻止。当计算器=0,及最后一个线程进来的时候,会执行cyclicbarrier的方法。执行完成会调用nextGeneration()唤醒其他所以的线程

  1. private void nextGeneration() {
  2. // signal completion of last generation
  3. trip.signalAll();
  4. // set up next generation
  5. count = parties;
  6. generation = new Generation();
  7. }