首页 > 代码库 > 关于CyclicBarrier的执行顺序
关于CyclicBarrier的执行顺序
- 认识CyclicBarrier, 先看两个文档介绍
CyclicBarrier(int parties, Runnable barrierAction)
Creates a new CyclicBarrier that will trip when the given number of parties (threads) are waiting upon it, and which will execute the given barrier action when the barrier is tripped, performed by the last thread entering the barrier.
int
await()
Waits until all parties have invoked await on this barrier.
- 举例,示例代码
1 public class Main { 2 3 private static CyclicBarrier barrier ; 4 5 public Main(){ 6 7 } 8 9 static class Worker implements Runnable{10 int id;11 12 public Worker(int i){13 id = i;14 }15 16 @Override17 public void run() {18 System.out.println("thread is working : "+id);19 20 try {21 barrier.await();22 } catch (InterruptedException e) {23 e.printStackTrace();24 } catch (BrokenBarrierException e) {25 e.printStackTrace();26 }27 28 System.out.println("thread is ending : "+id);29 }30 }31 32 public static void main(String[] args) {33 34 barrier = new CyclicBarrier(2, new Runnable() {35 @Override36 public void run() {37 try {38 Thread.sleep(3000);39 } catch (InterruptedException e) {40 e.printStackTrace();41 }42 System.out.println("Master is finished.......");43 }44 });45 46 for (int i=0;i<2;i++){47 Worker worker = new Worker(i);48 new Thread(worker).start();49 }50 51 }52 }
- 问题:parties满足全部进入await后,barrierAction与await的唤醒,谁先谁后?
- 实验结果: 示例代码执行结果
thread is working : 0
thread is working : 1
Master is finished.......
thread is ending : 1
thread is ending : 0
结果说明:CyclicBarrier中,当各参与方(parties)到达之后,构造函数中的barrier action会先执行,之后各线程的await才会再返回。
- JDK源代码佐证:
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 9 if (g.broken)10 throw new BrokenBarrierException();11 12 if (Thread.interrupted()) {13 breakBarrier();14 throw new InterruptedException();15 }16 17 int index = --count;18 if (index == 0) { // tripped19 boolean ranAction = false;20 try {21 final Runnable command = barrierCommand;22 if (command != null)23 command.run();24 ranAction = true;25 nextGeneration();26 return 0;27 } finally {28 if (!ranAction)29 breakBarrier();30 }31 }32 33 // loop until tripped, broken, interrupted, or timed out34 for (;;) {35 try {36 if (!timed)37 trip.await();38 else if (nanos > 0L)39 nanos = trip.awaitNanos(nanos);40 } catch (InterruptedException ie) {41 if (g == generation && ! g.broken) {42 breakBarrier();43 throw ie;44 } else {45 // We‘re about to finish waiting even if we had not46 // been interrupted, so this interrupt is deemed to47 // "belong" to subsequent execution.48 Thread.currentThread().interrupt();49 }50 }51 52 if (g.broken)53 throw new BrokenBarrierException();54 55 if (g != generation)56 return index;57 58 if (timed && nanos <= 0L) {59 breakBarrier();60 throw new TimeoutException();61 }62 }63 } finally {64 lock.unlock();65 }66 }
从代码可以看出,barrierCommand执行(21行)之后,才在finally里调用breakeBarrier(29行),从而唤醒其他线程。证明示例代码的运行结论。
关于CyclicBarrier的执行顺序
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。