zoukankan      html  css  js  c++  java
  • 关于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         @Override
    17         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             @Override
    36             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) {  // tripped
    19                 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 out
    34             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 not
    46                         // been interrupted, so this interrupt is deemed to
    47                         // "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     }
    JDK CyclicBarrier源代码

      从代码可以看出,barrierCommand执行(21行)之后,才在finally里调用breakeBarrier(29行),从而唤醒其他线程。证明示例代码的运行结论。

  • 相关阅读:
    ArcGIS API for javascript开发笔记(四)——GP服务调用之GP模型的规范化制作详解
    ArcGIS API for javascript开发笔记(三)——解决打印输出的中文为乱码问题
    ArcGIS API for javascript开发笔记(二)——解决ArcGIS Service中的服务在内网环境下无法进行javascript预览问题
    解决GP服务产生的结果无法自动发布为地图服务的问题
    解决oracle12c安装报“[INS-30131]执行安装程序验证所需的初始设置失败(原因:无法访问临时位置)”方法
    Pdf File Writer 中文应用(PDF文件编写器C#类库)
    七牛云存储客户端(本人开发,开源)
    如鹏网 net高级技术 第二章 委托和事件(复习)
    如鹏网 net高级技术 第一章 各种知识点(复习)
    写个QuartzHelper类
  • 原文地址:https://www.cnblogs.com/daition/p/7002660.html
Copyright © 2011-2022 走看看