zoukankan      html  css  js  c++  java
  • 并发库应用之八 & 循环路障CyclicBarrier应用

      JDK包位置:java.util.concurrent.CyclicBarrier

      一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。

      CyclicBarrier 支持一个可选的 Runnable 命令,在一组线程中的最后一个线程到达之后(但在释放所有线程之前),该命令只在每个屏障点运行一次。若再继续所有参与线程之前更新共享状态,此屏障操作 很有用。

    对应构造方法摘要:

      CyclicBarrier(int parties)

                 创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,但它不会在启动 barrier 时执行预定义的操作。

      CyclicBarrier(int parties, Runnable barrierAction)

                创建一个新的 CyclicBarrier,它将在给定数量的参与者(线程)处于等待状态时启动,并在启动 barrier 时执行给定的屏障操作,该操作由最后一个进入 barrier 的线程执行。

    方法摘要:

      int  await()                   在所有参与者都已经在此 barrier 上调用 await 方法之前,将一直等待。

      int  await(long timeout, TimeUnit unit)  在所有参与者都已经在此屏障上调用 await 方法之前将一直等待,或者超出了指定的等待时间

      int  getNumberWaiting()                 返回当前在屏障处等待的参与者数目。

      int  getParties()                       返回要求启动此 barrier 的参与者数目。

      boolean  isBroken()                   查询此屏障是否处于损坏状态。

      void  reset()                        将屏障重置为其初始状态。

      案例应用:组织人员(线程)郊游,约定一个时间地点(路障),人员陆续到达地点,等所有人员全部到达,开始到公园各玩各的,再到约定时间去食堂吃饭,等所有人到齐开饭……;依据此思想,用代码实现:三个线程干完各自的任务,在不同的时刻到达集合点后,就可以接着忙各自的工作去了,再到达新的集合点,再去忙各自的工作,到达集合点了用 CyclicBarrier 对象的 await 方法表示。

     1 import java.util.concurrent.CyclicBarrier;
     2 import java.util.concurrent.ExecutorService;
     3 import java.util.concurrent.Executors;
     4 
     5 public class CyclicBarrierTest {
     6     public static void main(String[] args) {
     7         //线程数动态变化,来一个就产生一个线程
     8         ExecutorService service = Executors.newCachedThreadPool();
     9         final CyclicBarrier cb = new CyclicBarrier(3); //包含有3个线程的容量
    10         for (int i = 0; i < 3; i++) { //3个集合地点
    11             Runnable runnable = new Runnable() {
    12                 public void run() {
    13                     try {
    14                         Thread.sleep((long) (Math.random() * 5000));
    15                         System.out.println(String.format("线程%s已经到达集合地点【1】,当前已有%d个已经到达,正在等候", Thread.currentThread().getName(), cb.getNumberWaiting()+1));
    16                         cb.await();
    17 
    18                         Thread.sleep((long) (Math.random() * 5000));
    19                         System.out.println(String.format("线程%s已经到达集合地点【2】,当前已有%d个已经到达,正在等候", Thread.currentThread().getName(), cb.getNumberWaiting()+1));
    20                         cb.await();
    21 
    22                         Thread.sleep((long) (Math.random() * 5000));
    23                         System.out.println(String.format("线程%s已经到达集合地点【3】,当前已有%d个已经到达,正在等候", Thread.currentThread().getName(), cb.getNumberWaiting()+1));
    24                         cb.await();
    25                     } catch (Exception e) {
    26                         e.printStackTrace();
    27                     }
    28                 }
    29             };
    30             service.execute(runnable);
    31         }
    32         service.shutdown();
    33     }
    34 }

    运行以上代码打印结果如下所示:

      

     提示:欢迎继续参看我相关的下一篇博客:并发库应用之九 & 到时计数器CountDownLatch应用

  • 相关阅读:
    清除某个数据库的所有数据库连接的存储过程
    IIS的Windows集成身份验证总结
    新项目的页面不要直接从PageBase继承
    安装Win2003 SP1遇到拒绝访问
    ASP.NET2.0站点跨服务器访问Sql Sever 2005 Reporting Service
    当CodeSmith不在时,续……
    Web讯雷导致IIS无法启动的问题
    Intro to eDiscovery in SharePoint, Exchange, and Lync 2013
    微软云平台
    团队开发博客
  • 原文地址:https://www.cnblogs.com/liang1101/p/6526121.html
Copyright © 2011-2022 走看看