java线程中CyclicBarrier的使用—实现一组线程“集齐”后,再进行其他操作

JDK1.6中的API中是这样介绍的:一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。CyclicBarrier 支持一个可选的 Runnable 命令,在一组线程中的最后一个线程到达之后(但在释放所有线程之前),该命令只在每个屏障点运行一次。若在继续所有参与线程之前更新共享状态,此屏障操作 很有用。 

拥有的方法:

java线程中CyclicBarrier的使用—实现一组线程“集齐”后,再进行其他操作_第1张图片


在某种需求中,比如一个大型的任务,常常需要分配好多子任务去执行,只有当所有子任务都执行完成时候,才能执行主任务,这时候,就可以选择CyclicBarrier了。 如:一群人打算去游玩,大家彼此先等待,大家集合好后才开始出发,分散活动后又在i指定地点集合碰面,这就好比整个公司的人员利用周末时间集体郊游一样,先各自从家出发到公司集合后,再同时出发到公园游玩,在指定地点集合后再同时开始就餐……。在这里CyclicBarrier就非常有用。看代码(张孝祥视频学习笔记):

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CyclicBarrierTest {
 public static void main(String [] args){
  ExecutorService service=Executors.newCachedThreadPool();
  final
CyclicBarrier cb=new CyclicBarrier(3);  //三个线程同时到达
  for(int i=0;i<3;i++){          
   Runnable runnable=new Runnable(){
    public void run(){
     try {
      Thread.sleep((long)(Math.random()*10000));
      System.out.println("线程"+Thread.currentThread().getName()+
        "即将到达集合地点1,当前已有"+(cb.getNumberWaiting()+1)+"个已到达"+
        (cb.getNumberWaiting()==2?"都到齐了,继续走啊":"正在等候"));
      try {
       cb.await();
      } catch (BrokenBarrierException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
      }
      Thread.sleep((long)(Math.random()*10000));
      System.out.println("线程"+Thread.currentThread().getName()+
        "即将到达集合地点2,当前已有"+(cb.getNumberWaiting()+1)+"个已到达"+
        (cb.getNumberWaiting()==2?"都到齐了,继续走啊":"正在等候"));
      try {
       cb.await();
      } catch (BrokenBarrierException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
      }
      Thread.sleep((long)(Math.random()*10000));
      System.out.println("线程"+Thread.currentThread().getName()+
        "即将到达集合地点3,当前已有"+(cb.getNumberWaiting()+1)+"个已到达"+
        (cb.getNumberWaiting()==2?"都到齐了,继续走啊":"正在等候"));
      try {
       cb.await();
      } catch (BrokenBarrierException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
      }
     } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
     }
    }
   };
   service.execute(runnable);
  }
  service.shutdown();
 }
}

运行结果:

线程pool-1-thread-3即将到达集合地点1,当前已有1个已到达正在等候
线程pool-1-thread-2即将到达集合地点1,当前已有2个已到达正在等候
线程pool-1-thread-1即将到达集合地点1,当前已有3个已到达都到齐了,继续走啊
线程pool-1-thread-1即将到达集合地点2,当前已有1个已到达正在等候
线程pool-1-thread-2即将到达集合地点2,当前已有2个已到达正在等候
线程pool-1-thread-3即将到达集合地点2,当前已有3个已到达都到齐了,继续走啊
线程pool-1-thread-2即将到达集合地点3,当前已有1个已到达正在等候
线程pool-1-thread-1即将到达集合地点3,当前已有2个已到达正在等候
线程pool-1-thread-3即将到达集合地点3,当前已有3个已到达都到齐了,继续走啊

线程中的锁存器CountDownLatch也能实现此效果,不太清楚此工具类的可以搜索相关内容了解一下:http://blog.csdn.net/chenleixing/article/details/42173593

你可能感兴趣的:(Cyclicbarrier,java线程,线程等待,并发同步,多个线程同时等待)