• java 线程之concurrent中的常用工具 CyclicBarrier


    一、CyclicBarrier 

      CyclicBarrier是一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。
      CyclicBarrier类似于CountDownLatch也是个计数器, 不同的是CyclicBarrier数的是调用了CyclicBarrier.await()进入等待的线程数, 当线程数达到了CyclicBarrier初始时规定的数目时,所有进入等待状态的线程被唤醒并继续。 CyclicBarrier就象它名字的意思一样,可看成是个障碍, 所有的线程必须到齐后才能一起通过这个障碍。 CyclicBarrier初始时还可带一个Runnable的参数,此Runnable任务在CyclicBarrier的数目达到后,所有其它线程被唤醒前被执行。

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

      public CyclicBarrier(int parties) { this(parties, null);}

    demo:

     1 package com.jalja.org.thread;
     2 import java.util.concurrent.CyclicBarrier;
     3 import java.util.concurrent.ExecutorService;
     4 import java.util.concurrent.Executors;
     5 public class LockTest {
     6     public static void main(String [] args){
     7         CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
     8         ExecutorService executorService= Executors.newFixedThreadPool(3);
     9         Runnable threadTest=null;
    10         for(int i=0;i<3;i++){
    11             threadTest=new ThreadTest(cyclicBarrier);
    12             executorService.execute(threadTest);
    13         }
    14         executorService.shutdown();
    15     }
    16 }
    17 class ThreadTest implements Runnable{
    18     private CyclicBarrier cyclicBarrier;
    19     public ThreadTest(CyclicBarrier cyclicBarrier){
    20         this.cyclicBarrier=cyclicBarrier;
    21     }
    22     public void run() {
    23         try {
    24             Thread.sleep((long)(Math.random()*10000));
    25             System.out.println(Thread.currentThread().getName()+"开始执行");
    26             cyclicBarrier.await();
    27         }catch (Exception e){
    28             e.printStackTrace();
    29         }
    30         System.out.println(Thread.currentThread().getName()+"执行结束");
    31     }
    32 }
    View Code

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

    public CyclicBarrier(int parties, Runnable barrierAction) {
            if (parties <= 0) throw new IllegalArgumentException();
            this.parties = parties;
            this.count = parties;
            this.barrierCommand = barrierAction;
        }

    demo: 如果在构造CyclicBarrier对象的时候传了一个Runnable对象进去,则每次到达公共屏障点的时候都最先执行这个传进去的Runnable,然后再执行处于等待的Runnable。如果把上面的例子改成下面这样:

     1 package com.jalja.org.thread;
     2 import java.util.concurrent.CyclicBarrier;
     3 import java.util.concurrent.ExecutorService;
     4 import java.util.concurrent.Executors;
     5 public class LockTest {
     6     public static void main(String [] args){
     7         CyclicBarrier cyclicBarrier = new CyclicBarrier(3, new Runnable() {
     8             public void run() {
     9                 System.out.println(Thread.currentThread().getName()+"======");
    10                 try {
    11                     Thread.sleep((long)(Math.random()*10000));
    12                 }catch (Exception e){
    13                     e.printStackTrace();
    14                 }
    15                 System.out.println(Thread.currentThread().getName()+"======>");
    16             }
    17         });
    18         ExecutorService executorService= Executors.newFixedThreadPool(3);
    19         Runnable threadTest=null;
    20         for(int i=0;i<3;i++){
    21             threadTest=new ThreadTest(cyclicBarrier);
    22             executorService.execute(threadTest);
    23         }
    24         executorService.shutdown();
    25     }
    26 }
    27 class ThreadTest implements Runnable{
    28     private CyclicBarrier cyclicBarrier;
    29     public ThreadTest(CyclicBarrier cyclicBarrier){
    30         this.cyclicBarrier=cyclicBarrier;
    31     }
    32     public void run() {
    33         try {
    34             Thread.sleep((long)(Math.random()*10000));
    35             System.out.println(Thread.currentThread().getName()+"开始执行");
    36             cyclicBarrier.await();
    37         }catch (Exception e){
    38             e.printStackTrace();
    39         }
    40         System.out.println(Thread.currentThread().getName()+"执行结束");
    41     }
    42 }
    View Code

    结果:

    pool-1-thread-2开始执行
    pool-1-thread-3开始执行
    pool-1-thread-1开始执行
    pool-1-thread-1======
    pool-1-thread-1======>
    pool-1-thread-1执行结束
    pool-1-thread-2执行结束
    pool-1-thread-3执行结束
  • 相关阅读:
    【TCP/IP】【网络基础】网页访问流程
    【linux】【rpm】确定程序是否 rpm 安装
    【linux】【CPU】【x86】平台说明
    【linux】【进程】stand alone 与 super daemon 区别
    【内存】堆内存和栈内存
    【英语】【音标】元音字母 和 开音节 闭音节
    【php】【异步】php实现异步的几种方法
    【操作系统】多处理器系统的用户模式和特权模式
    张量漫谈(第三篇)
    张量漫谈(前两篇)
  • 原文地址:https://www.cnblogs.com/jalja/p/7247411.html
Copyright © 2020-2023  润新知