zoukankan      html  css  js  c++  java
  • Java并发编程核心方法与框架-CyclicBarrier的使用

    CyclicBarrier类似于CountDownLatch也是个计数器,不同的是CyclicBarrier数的是调用了CyclicBarrier.await()进入等待的线程数,当线程数达到了CyclicBarrier初始时规定的数目时,所有进入等待状态的线程被唤醒并继续。 CyclicBarrier就象它名字的意思一样,可看成是个障碍,所有的线程必须到齐后才能一起通过这个障碍。CyclicBarrier初始时还可带一个Runnable的参数,此Runnable任务在CyclicBarrier的数目达到后,所有其它线程被唤醒前被执行。


    • 构造方法摘要
    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()//将屏障重置为其初始状态。
    

    public class CyclicBarrierTest {
    	public static void main(String[] args) {
    		ExecutorService service = Executors.newCachedThreadPool();
    		final CyclicBarrier cb = new CyclicBarrier(3);//创建CyclicBarrier对象并设置3个公共屏障点
    		for (int i = 0; i < 3; i++) {
    			Runnable runnable = new Runnable() {
    				
    				@Override
    				public void run() {
    					try {
    						Thread.sleep((long)(Math.random()*10000));
    						System.out.println("线程" + Thread.currentThread().getName() + "即将到达集合地点1,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");   
    						cb.await();//到此如果没有达到公共屏障点,则该线程处于等待状态,如果达到公共屏障点则所有处于等待的线程都继续往下运行
    						Thread.sleep((long)(Math.random()*10000));
    						System.out.println("线程" + Thread.currentThread().getName() + "即将到达集合地点2,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");   
    						cb.await();
    						Thread.sleep((long)(Math.random()*10000));
    						System.out.println("线程" + Thread.currentThread().getName() + "即将到达集合地点3,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");   
    						cb.await();
    					} catch (InterruptedException | BrokenBarrierException e) {
    						e.printStackTrace();
    					}  
    				}
    			};
    			service.execute(runnable);
    		}
    		service.shutdown();
    	}
    }
    

    程序运行结果如下:

    线程pool-1-thread-3即将到达集合地点1,当前已有0个已经到达,正在等候
    线程pool-1-thread-1即将到达集合地点1,当前已有1个已经到达,正在等候
    线程pool-1-thread-2即将到达集合地点1,当前已有2个已经到达,正在等候
    线程pool-1-thread-3即将到达集合地点2,当前已有0个已经到达,正在等候
    线程pool-1-thread-2即将到达集合地点2,当前已有1个已经到达,正在等候
    线程pool-1-thread-1即将到达集合地点2,当前已有2个已经到达,正在等候
    线程pool-1-thread-3即将到达集合地点3,当前已有0个已经到达,正在等候
    线程pool-1-thread-1即将到达集合地点3,当前已有1个已经到达,正在等候
    线程pool-1-thread-2即将到达集合地点3,当前已有2个已经到达,正在等候
    

    使用第二种构造方法

    public class CyclicBarrierTest {
    	public static void main(String[] args) {
            ExecutorService service = Executors.newCachedThreadPool();
            //final  CyclicBarrier cb = new CyclicBarrier(3);//创建CyclicBarrier对象并设置3个公共屏障点
            final  CyclicBarrier cb = new CyclicBarrier(3,new Runnable(){
                @Override
                public void run() {
                    System.out.println("********你们到齐了我就执行***********");
                }
            });
            for(int i=0; i<5; i++){
                Runnable runnable = new Runnable(){
                        public void run(){
                        try {
                            Thread.sleep((long)(Math.random()*10000));    
                            System.out.println("线程" + Thread.currentThread().getName() + "即将到达集合地点1,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");                        
                            cb.await();//到此如果没有达到公共屏障点,则该线程处于等待状态,如果达到公共屏障点则所有处于等待的线程都继续往下运行
                            Thread.sleep((long)(Math.random()*10000));    
                            System.out.println("线程" + Thread.currentThread().getName() + "即将到达集合地点2,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");                        
                            cb.await();    //这里CyclicBarrier对象又可以重用
                            Thread.sleep((long)(Math.random()*10000));    
                            System.out.println("线程" + Thread.currentThread().getName() + "即将到达集合地点3,当前已有" + cb.getNumberWaiting() + "个已经到达,正在等候");                        
                            cb.await();                        
                        } catch (Exception e) {
                            e.printStackTrace();
                        }                
                    }
                };
                service.execute(runnable);
            }
            service.shutdown();
        }
    }
    

    程序运行结果如下:

    线程pool-1-thread-2即将到达集合地点1,当前已有0个已经到达,正在等候
    线程pool-1-thread-1即将到达集合地点1,当前已有1个已经到达,正在等候
    线程pool-1-thread-3即将到达集合地点1,当前已有2个已经到达,正在等候
    ********你们到齐了我就执行***********
    线程pool-1-thread-1即将到达集合地点2,当前已有0个已经到达,正在等候
    线程pool-1-thread-3即将到达集合地点2,当前已有1个已经到达,正在等候
    线程pool-1-thread-2即将到达集合地点2,当前已有2个已经到达,正在等候
    ********你们到齐了我就执行***********
    线程pool-1-thread-3即将到达集合地点3,当前已有0个已经到达,正在等候
    线程pool-1-thread-1即将到达集合地点3,当前已有1个已经到达,正在等候
    线程pool-1-thread-2即将到达集合地点3,当前已有2个已经到达,正在等候
    ********你们到齐了我就执行***********
    
  • 相关阅读:
    普通函数跟箭头函数中this的指向问题
    vue之router学习笔记
    vue之登录和token处理
    vue之router钩子函数
    eslint----standard 代码规范
    vscode----配置vue开发环境
    vue----安装教程
    vue----全局组件,局部组件
    vue----常用实例方法--$mount(),$destroy(),$watch(),$forceUpdate()
    vue----生命周期
  • 原文地址:https://www.cnblogs.com/umgsai/p/5671638.html
Copyright © 2011-2022 走看看