首页 > 代码库 > java 线程 新类库中的构件 CyclicBarrier使用

java 线程 新类库中的构件 CyclicBarrier使用

package org.rui.thread.newc;

import java.util.ArrayList;
import java.util.List;
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;

/**
 * 赛马游戏 CyclicBarrier
 * 
 * @author lenovo
 * 
 */
class Horse implements Runnable {
	private static int counter = 0;
	private final int id = counter++;
	private int strides = 0;
	private static Random rand = new Random(47);
	private static CyclicBarrier barrier;

	public Horse(CyclicBarrier b) {
		barrier = b;
	}

	public synchronized int getStrides() {
		return strides;
	}

	@Override
	public void run() {
		try {
			while (!Thread.interrupted()) {
				synchronized (this) {
					//每场比赛都会加上随机 跨过的数字 0,1 or 2
					strides += rand.nextInt(3);// produces 0,1 or 2
				}
				// 等待所有的马都准备完毕,当所有的马向前移动时,cyclicBarrier将自动调用runnable栅栏动作任务,按顺序显示马和终点的位置
				barrier.await();

			}

		} catch (InterruptedException e) {

		} catch (BrokenBarrierException e) {
			throw new RuntimeException(e);
		}
	}

	public String toString() {
		return "Horse" + id + " ";
	}

	// 轨道
	public String tracks() {
		StringBuilder s = new StringBuilder();
		for (int i = 0; i < getStrides(); i++) {
			s.append("*");
		}
		s.append(id);
		return s.toString();
	}
}

public class HorseRace {
	static final int FINISH_LINE = 15;// 结束 行
	private List<Horse> horses = new ArrayList<Horse>();
	private ExecutorService exec = Executors.newCachedThreadPool();
	private CyclicBarrier barrier;

	public HorseRace(int nHorses, final int pause) {
		
		barrier = new CyclicBarrier(nHorses/*等待的数量*/, new Runnable() {

			@Override
			public void run() {
				//打印信息 
				StringBuilder sb = new StringBuilder();
				for (int i = 0; i < FINISH_LINE; i++) {
					sb.append("=");// 赛马场上的栅栏
				}
				System.out.println(sb);
				for (Horse horse : horses) {
					System.out.println(horse.tracks());
				}
				for (Horse horse : horses) {
					//System.out.println("strides:@@@@@@@" + horse.getStrides());
					if (horse.getStrides() >= FINISH_LINE) {//
						System.out.println(horse + "赢得!");
						exec.shutdownNow();
						return;
					}
				}

				try {
					TimeUnit.MILLISECONDS.sleep(pause);
				} catch (InterruptedException e) {
					System.out.println("barrier-action sleep interrupted");
				}
			}
		});

		// 一旦所有的马都越过了栅栏,它就会自动地为下一回合比赛做好准备
		for (int i = 0; i < nHorses; i++) {
			Horse horse = new Horse(barrier);//每个马都分配一个barrier
			horses.add(horse);
			exec.execute(horse);
		}
	}

	/**
	 * main
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		int nHorses = 7; //指定马的数量
		int pause = 200;//停顿时间
		String[] arg = {};

		if (arg.length > 0) {// optional argument
			int n = new Integer(arg[0]);
			nHorses = n > 0 ? n : nHorses;
		}
		if (arg.length > 1) {// optional argument
			int p = new Integer(arg[1]);
			pause = p > -1 ? p : pause;
		}

		// 竞赛
		new HorseRace(nHorses, pause);

	}

}
/**
 ===========================================================================
**0
**1
*2
**3
*4
**5
*6
===========================================================================
**0
***1
*2
**3
*4
***5
***6
===========================================================================
***0
****1
***2
***3
**4
*****5
****6
===========================================================================
*****0
****1
*****2
****3
**4
******5
****6
===========================================================================
******0
****1
******2
*****3
****4
******5
*****6
===========================================================================
******0
******1
******2
******3
****4
*******5
*****6
===========================================================================
*******0
******1
*******2
******3
*****4
********5
*******6
===========================================================================
********0
******1
********2
*******3
*******4
*********5
*********6
===========================================================================
********0
******1
*********2
*******3
*********4
*********5
*********6
===========================================================================
**********0
*******1
**********2
********3
*********4
***********5
*********6
===========================================================================
**********0
*******1
************2
*********3
*********4
*************5
*********6
===========================================================================
************0
*******1
*************2
***********3
**********4
***************5
***********6
===========================================================================
************0
********1
*************2
*************3
***********4
***************5
*************6
===========================================================================
**************0
********1
*************2
*************3
*************4
...
...
...此处省略打印线
===========================================================================
**********************************************************************0
*******************************************************1
******************************************************************2
***********************************************************************3
***********************************************************************4
***********************************************************************5
*************************************************************6
===========================================================================
***********************************************************************0
*******************************************************1
*******************************************************************2
*************************************************************************3
***********************************************************************4
*************************************************************************5
***************************************************************6
===========================================================================
************************************************************************0
********************************************************1
*******************************************************************2
***************************************************************************3
***********************************************************************4
***************************************************************************5
****************************************************************6
Horse3 赢得!

 */

一个容易理解的张孝祥老师讲解例子 

package test;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
 * CyclicBarrier 应用
 * @author lenovo
 *
 */
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) {
							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) {
							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) {
							e.printStackTrace();
						}
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			};
			service.execute(runnable);
		}
		service.shutdown();
	}
}

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




java 线程 新类库中的构件 CyclicBarrier使用