zoukankan      html  css  js  c++  java
  • java并发编程之CyclicBarrier

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

     


    CyclicBarrier 支持一个可选的 Runnable 命令。在一组线程中的最后一个线程到达之后(但在释放全部线程之前),该命令仅仅在每一个屏障点执行一次。若在继续全部參与线程之前更新共享状态。此屏障操作 非常实用。

     
     
    CountDownLatch : 一个线程(或者多个), 等待另外N个线程完毕某个事情之后才干运行。

    CyclicBarrier       : N个线程相互等待,不论什么一个线程完毕之前,全部的线程都必须等待。

    这样应该就清楚一点了,对于CountDownLatch来说。重点是那个“一个线程”, 是它在等待, 而另外那N的线程在把“某个事情”做完之后能够继续等待。能够终止。而对于CyclicBarrier来说。重点是那N个线程。他们之间不论什么一个没有完毕,全部的线程都必须等待。


    package com.lala.shop;
    
    import java.util.Random;
    import java.util.concurrent.BrokenBarrierException;
    import java.util.concurrent.CyclicBarrier;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.TimeUnit;
    
    /**
     *  这里演示了一个样例:五个人一同去买 衬衫、裤子、鞋子。
     *  所有人必须先所有买完衬衫,然后才干去买裤子,所有买完裤子之后,在去买鞋子。所有买完鞋子之后。事情运行完毕
     */
    public class CyclicBarrierDemo 
    {
    	public static void main(String[] args) 
    	{
    		CyclicBarrier cb = new CyclicBarrier(5, new Runnable(){
    			public void run()
    			{
    				System.out.println("人已经到齐,准备下一步...");
    			}
    		});
    		ExecutorService runner = Executors.newFixedThreadPool(5);
    		runner.submit(new Shopping("李大嘴", cb));
    		runner.submit(new Shopping("白展堂", cb));
    		runner.submit(new Shopping("郭芙蓉", cb));
    		runner.submit(new Shopping("佟湘玉", cb));
    		runner.submit(new Shopping("吕秀才", cb));
    		runner.shutdown();
    	}
    }
    
    class Shopping implements Runnable
    {
    	private String user;
    	private CyclicBarrier cb;
    	
    	public Shopping(String user, CyclicBarrier cb)
    	{
    		this.user = user;
    		this.cb = cb;
    	}
    	
    	public void run()
    	{
    		try 
    		{
    			long shirtTime = getRandomTime();
    			
    			TimeUnit.SECONDS.sleep(shirtTime);
    			
    			System.out.println(user + "买完衬衫,花了时间:" + shirtTime);
    			
    			cb.await();
    			
    			long pantsTime = getRandomTime();
    			
    			TimeUnit.SECONDS.sleep(pantsTime);
    			
    			System.out.println(user + "买完裤子,花了时间:" + pantsTime);
    			
    			cb.await();
    			
    			long shoseTime = getRandomTime();
    			
    			TimeUnit.SECONDS.sleep(shoseTime);
    			
    			System.out.println(user + "买完鞋子,花了时间:" + shoseTime);
    			
    			cb.await();
    			
    			System.out.println(user + "东西已经买齐了,回家");
    			
    		} catch (InterruptedException | BrokenBarrierException e) 
    		{
    			e.printStackTrace();
    		}
    	}
    	
    	private long getRandomTime()
    	{
    		return new Random().nextInt(9) + 1;
    	}
    }


    输出结果为:


    吕秀才买完衬衫,花了时间:1
    白展堂买完衬衫。花了时间:1
    佟湘玉买完衬衫,花了时间:3
    李大嘴买完衬衫,花了时间:8
    郭芙蓉买完衬衫。花了时间:9
    人已经到齐。准备下一步...
    白展堂买完裤子,花了时间:4
    佟湘玉买完裤子,花了时间:4
    吕秀才买完裤子。花了时间:5
    郭芙蓉买完裤子。花了时间:8
    李大嘴买完裤子,花了时间:9
    人已经到齐,准备下一步...
    吕秀才买完鞋子,花了时间:1
    白展堂买完鞋子。花了时间:2
    佟湘玉买完鞋子,花了时间:7
    郭芙蓉买完鞋子。花了时间:8
    李大嘴买完鞋子,花了时间:8
    人已经到齐。准备下一步...
    李大嘴东西已经买齐了。回家
    吕秀才东西已经买齐了,回家
    白展堂东西已经买齐了。回家
    郭芙蓉东西已经买齐了,回家
    佟湘玉东西已经买齐了,回家

  • 相关阅读:
    分布式发布订阅消息系统 Kafka 架构设计[转]
    KAFKA分布式消息系统[转]
    文本协议与二进制协议的选择
    实现程序的热升级
    实现程序的热升级
    一个Socket数据处理模型
    关于GC进行垃圾回收的时机
    多线程
    线程同步(AutoResetEvent与ManualResetEvent)
    异步
  • 原文地址:https://www.cnblogs.com/clnchanpin/p/7111639.html
Copyright © 2011-2022 走看看