zoukankan      html  css  js  c++  java
  • Java多线程与并发库高级应用之公共屏障点CyclicBarrier

    一个小队去登山,每位队员登山的速度不同。山上有几个集合点,在每一集合点处,先到达的队员只有等后面的队员全部到达集合点后才能继续向下一个集合点出发。
    JDK1.5提供的CyclicBarrier模拟了这种情况。每一个线程相当于一个登山队员,CyclicBarrier相当于山上的集合点。只有等所有线程都执行到了CyclicBarrier后才可以继续向下执行。
    CyclicBarrier允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。

    CyclicBarrier有两个构造器:

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

    在程序某一处调用CyclicBarrier对象的await()方法可以设置公共屏障点。调用getNumberWaiting()方法返回当前在屏障处等待的参与者数目。

    见下面程序
    1. public class CyclicBarrierDemo {  
    2.   
    3.     public static void main(String[] args) {  
    4.           
    5.         //线程池  
    6.         ExecutorService pool = Executors.newCachedThreadPool();  
    7.         //公共屏障点,参与者数量为3  
    8.         final CyclicBarrier barrier = new CyclicBarrier(3);  
    9.           
    10.         //创建3个线程  
    11.         for(int i = 0; i < 3; i++){  
    12.             Runnable target = new Runnable() {  
    13.                 @Override  
    14.                 public void run() {  
    15.                     try{  
    16.                         Thread.sleep((long)(Math.random()*10000));  
    17.                         System.out.println(Thread.currentThread().getName() +   
    18.                                 "-即将到达集合点1,当前有" + (barrier.getNumberWaiting()+1) + "个线程已到达," +  
    19.                                 (barrier.getNumberWaiting() == 2?"都到齐了,继续出发":"等待中..."));  
    20.                         //第一个屏障点  
    21.                         barrier.await();  
    22.                           
    23.                         Thread.sleep((long)(Math.random()*10000));  
    24.                         System.out.println(Thread.currentThread().getName() +   
    25.                                 "-即将到达集合点2,当前有" + (barrier.getNumberWaiting()+1) + "个线程已到达," +  
    26.                                 (barrier.getNumberWaiting() == 2?"都到齐了,继续出发":"等待中..."));  
    27.                         //第二个屏障点  
    28.                         barrier.await();  
    29.                           
    30.                         Thread.sleep((long)(Math.random()*10000));  
    31.                         System.out.println(Thread.currentThread().getName() +   
    32.                                 "-即将到达集合点3,当前有" + (barrier.getNumberWaiting()+1) + "个线程已到达," +  
    33.                                 (barrier.getNumberWaiting() == 2?"都已到达":"等待中..."));  
    34.                         //第三个屏障点  
    35.                         barrier.await();  
    36.                     }catch(Exception e){  
    37.                         e.printStackTrace();  
    38.                     }  
    39.                 }  
    40.             };  
    41.               
    42.             pool.execute(target);  
    43.         }  
    44.         pool.shutdown();  
    45.     }  
    46.   
    47. }  

    运行程序

    看到3个线程都到达屏障点后才继续向下执行。
  • 相关阅读:
    比较简短的拼音首字母自定义函数
    程序员之路——一个老程序员对刚上大学的学弟学妹的忠告
    Android应用程序请求SurfaceFlinger服务渲染Surface的过程分析
    对当前软件行业的一点点感想
    调用opengl程序代码
    windows平台下,c++获取cpu型号,读取注册表获取系统软硬件信息代码
    应该被记住的8位Java人物
    软件开发高手须掌握的4大SQL精髓语句(二)
    如何建立一个网站(我的5年经验谈)
    vs 2010 express 查看malloc能分配多少内存
  • 原文地址:https://www.cnblogs.com/sfce/p/3701636.html
Copyright © 2011-2022 走看看