线程:CyclicBarrier同步工具类
一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点。比如公司组织活动出去玩,需要在公司门口一起搭车去。每个人从家里出发去公司门口,到达的时间肯定先后不一样,所以公司的车要一直等待,等所有人到齐后,才开车出发。CyclicBarrier就类似这样的功能,当所有线程到达"屏蔽点"的时候,才往下走。
具体等待多少根线程到达,可以在构造方法里指定CyclicBarrier(int parties)。
当你的parties设为3的时候,假设只有2根线程到达此处,那程序会一直在此等待。可以设置timeout,当到达时间时,会抛出TimeoutException异常;当有4根线程的时候,只要任意3根到达屏蔽点,就会继续往下执行。
示例代码:
1 package ch03; 2 3 import java.util.Random; 4 import java.util.concurrent.CyclicBarrier; 5 import java.util.concurrent.ExecutorService; 6 import java.util.concurrent.Executors; 7 import java.util.concurrent.TimeUnit; 8 9 public class CyclicBarrierTest { 10 11 public static void main(String[] args) { 12 final int count = 3; 13 //线程池 14 ExecutorService threadPool = Executors.newFixedThreadPool(count); 15 //实例化CyclicBarrier对象,并指定当到达屏蔽点的时候, 16 //需要执行的 操作,该操作由最后一个到达的线程执行。 17 final CyclicBarrier barrier = new CyclicBarrier(count, new Runnable() { 18 19 @Override 20 public void run() { 21 System.out.println("前往下一个地点..."); 22 } 23 }); 24 System.out.println("参与个数:"+barrier.getParties()); 25 for(int i=0; i<count; i++){ 26 Runnable runnable = new Runnable() { 27 28 @Override 29 public void run() { 30 try{ 31 Thread.sleep(new Random().nextInt(5000)); 32 System.out.println(Thread.currentThread().getName()+ 33 "到达指定地点A,当前已有"+ 34 (barrier.getNumberWaiting()+1)+"人到达,"+ 35 (barrier.getNumberWaiting() == (count -1) ? "继续前进...":"等待其他人到来")); 36 //等待3个线程全部到达,当等待时间超过15s时,将报错 37 barrier.await(10, TimeUnit.SECONDS); 38 39 Thread.sleep(new Random().nextInt(5000)); 40 System.out.println(Thread.currentThread().getName()+"到达指定地点B,当前已有"+ 41 (barrier.getNumberWaiting()+1)+"人到达,"+ 42 (barrier.getNumberWaiting() == (count -1) ? "继续前进...":"等待其他人到来")); 43 barrier.await(); 44 }catch(Exception e){ 45 e.printStackTrace(); 46 } 47 } 48 }; 49 threadPool.execute(runnable); 50 } 51 threadPool.shutdown(); 52 } 53 54 }
输出结果: