美文网首页JUC
CyclicBarrier | 译

CyclicBarrier | 译

作者: zlzl_ | 来源:发表于2022-11-02 00:15 被阅读0次

    https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CyclicBarrier.html

    Class CyclicBarrier

    java.util.concurrent.CyclicBarrier
    public class CyclicBarrier extends 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) {
         // log the completion of this iteration
       }
    

    CyclicBarrier 对失败的同步尝试使用全有或全无中断模型:如果线程由于中断、故障或超时而过早离开屏障点,则在该屏障点等待的所有其他线程也会通过 BrokenBarrierException(或 InterruptedException 如果他们也几乎同时被打断)。

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

    Constructor Detail

    public CyclicBarrier(int parties, Runnable barrierAction)

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

    public CyclicBarrier(int parties)

    创建一个新的 CyclicBarrier,它将在给定数量的参与方(线程)等待它时触发,并且在触发障碍时不执行预定义的操作。

    public int getParties()

    返回触发此障碍所需的参与方数量。

    public int await() throws InterruptedException, BrokenBarrierException

    等到所有各方都在此屏障上调用了 await。
    如果当前线程不是最后到达的,则出于线程调度目的将其禁用并处于休眠状态,直到发生以下情况之一:

    • 最后一个线程到达;或者
    • 其他一些线程中断当前线程;或者
    • 其他一些线程中断了其他等待线程之一;或者
    • 其他一些线程在等待屏障时超时;或者
    • 其他一些线程在此屏障上调用 reset()。
      如果当前线程:
    • 在进入此方法时设置其中断状态;或者
    • 等待时被打断
      然后抛出 InterruptedException 并清除当前线程的中断状态。
      如果在任何线程等待时屏障被 reset(),或者在调用 await 时屏障被破坏,或者在任何线程正在等待时,则抛出 BrokenBarrierException。

    如果任何线程在等待时被中断,那么所有其他等待的线程都会抛出 BrokenBarrierException 并且屏障处于损坏状态。

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

    public int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException

    等待,直到所有各方都在此屏障上调用了 await,或者指定的等待时间过去。
    如果当前线程不是最后到达的,则出于线程调度目的将其禁用并处于休眠状态,直到发生以下情况之一:

    • 最后一个线程到达;或者

    • 指定的超时时间过去;或者

    • 其他一些线程中断当前线程;或者

    • 其他一些线程中断了其他等待线程之一;或者

    • 其他一些线程在等待屏障时超时;或者

    • 其他一些线程在此屏障上调用 reset()。
      如果当前线程:

    • 在进入此方法时设置其中断状态;或者

    • 等待时被打断
      然后抛出 InterruptedException 并清除当前线程的中断状态。
      如果指定的等待时间过去,则抛出 TimeoutException。如果时间小于或等于零,则该方法根本不会等待。

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

    如果任何线程在等待时被中断,那么所有其他等待的线程都会抛出 BrokenBarrierException 并且屏障处于损坏状态。

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

    public boolean isBroken()

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

    public void reset()

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

    public int getNumberWaiting()

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

    相关文章

      网友评论

        本文标题:CyclicBarrier | 译

        本文链接:https://www.haomeiwen.com/subject/mmgdtdtx.html