Java并发编程:CyclicBarrier可重用线程组等待同步辅助类

原文地址:https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CyclicBarrier.html

java.util.concurrent中

类CyclicBarrier


  •  
    公共类CyclicBarrier 
    扩展了Object
    一种同步辅助工具,允许一组线程全部等待彼此到达公共障碍点。CyclicBarriers在涉及固定大小的线程方的程序中很有用,这些线程必须偶尔等待彼此。屏障称为 循环,因为它可以在等待线程释放后重新使用。

    一的CyclicBarrier支持可选的Runnable是每个屏障点运行一次命令,在党内的最后一个线程到达之后,但任何线程都被释放之前。在任何一方继续之前,此屏障操作对于更新共享状态非常有用。

    示例用法:以下是在并行分解设计中使用屏障的示例:

    class Solver {
       final int N;
       final float[][] data;
       final CyclicBarrier barrier;
    
       class Worker implements Runnable {
         int myRow;
         Worker(int row) { myRow = row; }
         public void run() {
           while (!done()) {
             processRow(myRow);
    
             try {
               barrier.await();
             } catch (InterruptedException ex) {
               return;
             } catch (BrokenBarrierException ex) {
               return;
             }
           }
         }
       }
    
       public Solver(float[][] matrix) {
         data = matrix;
         N = matrix.length;
         barrier = new CyclicBarrier(N,
                                     new Runnable() {
                                       public void run() {
                                         mergeRows(...);
                                       }
                                     });
         for (int i = 0; i < N; ++i)
           new Thread(new Worker(i)).start();
    
         waitUntilDone();
       }
     }
    这里,每个工作线程处理一行矩阵,然后在屏障处等待,直到所有行都被处理完毕。处理完所有行后Runnable,将执行提供的屏障操作并合并行。如果合并确定已找到解决方案,则done()将返回 true并且每个工作程序将终止。

    如果屏障操作不依赖于各方在执行时被暂停,那么该方中的任何线程都可以在释放时执行该操作。为了促进这一点,每次调用都会 await()返回该线程到达屏障的到达索引。然后,您可以选择应执行屏障操作的线程,例如:

      if(barrier.await()== 0){
         //记录此迭代的完成情况
       }

    该的CyclicBarrier使用了失败的同步尝试全或无破损模式:如果一个线程离开屏障点过早,因为中断,失败或超时,其他所有线程在该屏障点等待也将通过离开异常BrokenBarrierException(或者 InterruptedException,如果他们也几乎在同一时间被打断了)。

    内存一致性效果:在调用之前的线程中的操作 await() 发生在 作为屏障操作一部分的操作之前,而操作又 发生在await()其他线程中的相应成功返回之后的操作之前

    以来:

    1.5

    也可以看看:

    CountDownLatch

  • 方法摘要

    方法 
    修饰符和类型方法和描述
    intawait()

    等待所有各方都 在这个障碍上等待。

    intawait(long timeout, TimeUnit unit)

    等待所有各方援引 等待这个屏障,或指定的等待时间。

    intgetNumberWaiting()

    返回当前在屏障处等待的方数。

    intgetParties()

    返回跳过此障碍所需的参与方数量。

    booleanisBroken()

    查询此屏障是否处于损坏状态。

    voidreset()

    将屏障重置为其初始状态。

  • 构造函数摘要

    构造函数 
    构造函数和描述
    CyclicBarrier(int parties)

    创建一个新的CyclicBarrier,当给定数量的各方(线程)等待它时将跳闸,并且当屏障被触发时不执行预定义的操作。

    CyclicBarrier(int parties, Runnable barrierAction)

    创建一个新的CyclicBarrier,当给定数量的各方(线程)正在等待它时将跳闸,并且当屏障被触发时执行给定的屏障动作,由进入屏障的最后一个线程执行。

  • 方法细节

    • getParties

      public int getParties()

      返回跳过此障碍所需的参与方数量。

      返回:

      此障碍所需的政党数量

    • 等待

      public int await()
                抛出InterruptedExceptionBrokenBarrierException
      等待所有各方都 在这个障碍上等待。

      如果当前线程不是最后到达的线程,那么它将被禁用以进行线程调度,并且在发生以下任何一种情况之前处于休眠状态:

      • 最后一个线程到了; 要么
      • 其他一些线程会中断 当前线程; 要么
      • 其他一些线程会中断其他 一个等待线程; 要么
      • 其他一些线程在等待屏障时超时; 要么
      • 其他一些线程reset()在这个障碍上调用。

      如果当前线程:

      • 在进入此方法时设置其中断状态; 要么
      • 在等待时 被打断
      InterruptedException抛出 然后清除当前线程的中断状态。

      如果屏障是reset()在任何线程正在等待,或者在调用await时 屏障被破坏,或者在任何线程正在等待时,则 抛出该屏障。 BrokenBarrierException

      如果任何线程在等待时被中断,则所有其他等待线程将抛出 BrokenBarrierException并且屏障处于断开状态。

      如果当前线程是要到达的最后一个线程,并且在构造函数中提供了非null屏障操作,则当前线程在允许其他线程继续之前运行该操作。如果在屏障操作期间发生异常,则该异常将在当前线程中传播,并且屏障处于断开状态。

      返回:

      当前线程的到达索引,其中index getParties()- 1表示第一个到达,零表示最后到达

      抛出:

      InterruptedException - 如果当前线程在等待时被中断

      BrokenBarrierException- 如果另一个线程在当前线程等待时被中断或超时,或者屏障被重置,或者屏障在await被调用时被破坏,或者屏障操作(如果存在)因异常而失败。

    • 等待

      public int await(long timeout,
               TimeUnit  unit)
                抛出InterruptedExceptionBrokenBarrierExceptionTimeoutException
      等待所有各方援引 等待这个屏障,或指定的等待时间。

      如果当前线程不是最后到达的线程,那么它将被禁用以进行线程调度,并且在发生以下任何一种情况之前处于休眠状态:

      • 最后一个线程到了; 要么
      • 指定的超时时间过去了; 要么
      • 其他一些线程会中断 当前线程; 要么
      • 其他一些线程会中断其他 一个等待线程; 要么
      • 其他一些线程在等待屏障时超时; 要么
      • 其他一些线程reset()在这个障碍上调用。

      如果当前线程:

      • 在进入此方法时设置其中断状态; 要么
      • 在等待时 被打断
      InterruptedException抛出 然后清除当前线程的中断状态。

      如果经过指定的等待时间则TimeoutException 抛出。如果时间小于或等于零,则该方法将不会等待。

      如果屏障是reset()在任何线程正在等待,或者在调用await时 屏障被破坏,或者在任何线程正在等待时,则 抛出该屏障。 BrokenBarrierException

      如果任何线程在等待时被中断,则所有其他等待线程将抛出BrokenBarrierException并且屏障处于断开状态。

      如果当前线程是要到达的最后一个线程,并且在构造函数中提供了非null屏障操作,则当前线程在允许其他线程继续之前运行该操作。如果在屏障操作期间发生异常,则该异常将在当前线程中传播,并且屏障处于断开状态。

      参数:

      timeout - 等待障碍的时间

      unit - 超时参数的时间单位

      返回:

      当前线程的到达索引,其中index getParties()- 1表示第一个到达,零表示最后到达

      抛出:

      InterruptedException - 如果当前线程在等待时被中断

      TimeoutException - 如果超过指定的超时

      BrokenBarrierException- 如果另一个线程在当前线程等待时被中断或超时,或者屏障被重置,或者屏幕在await被调用时被破坏,或者屏障操作(如果存在)因异常而失败

    • 被打破

      public boolean isBroken()

      查询此屏障是否处于损坏状态。

      返回:

      true如果一方或多方因施工或上次重置导致中断或超时,或由于例外导致屏障措施失败而突破此障碍; false除此以外。

    • 重启

      public void reset()

      将屏障重置为其初始状态。如果任何一方当前正在等待屏障,他们将返回一个 BrokenBarrierException。注意, 由于其他原因发生破损重置可能很复杂; 线程需要以其他方式重新同步,并选择一个来执行重置。可能优选的是为随后的使用创建新的屏障。

    • getNumberWaiting

      public int getNumberWaiting()

      返回当前在屏障处等待的方数。此方法主要用于调试和断言。

      返回:

      目前被封锁的政党数量 await()

  • 构造函数详细信息

    • 的CyclicBarrier

      public CyclicBarrier(int parties,
                    Runnable  barrierAction)

      创建一个新的CyclicBarrier,当给定数量的各方(线程)正在等待它时将跳闸,并且当屏障被触发时执行给定的屏障动作,由进入屏障的最后一个线程执行。

      参数:

      parties- 在await() 触发屏障之前必须调用的线程数

      barrierAction- 屏障跳闸时执行的命令,或者null没有操作的命令

      抛出:

      IllegalArgumentException- 如果parties小于1

    • 的CyclicBarrier

      public CyclicBarrier(int parties)

      创建一个新的CyclicBarrier,当给定数量的各方(线程)等待它时将跳闸,并且当屏障被触发时不执行预定义的操作。

      参数:

      parties- 在await() 触发屏障之前必须调用的线程数

      抛出:

      IllegalArgumentException- 如果parties小于1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值