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个已到达都到齐了,继续走啊
 */
时间: 2024-08-14 21:58:36

java 线程 新类库中的构件 CyclicBarrier使用的相关文章

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

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGlhbmdydWkxOTg4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" > package org.rui.thread.newc; import java.util.Random; import java.util.concurrent.CountDownLatch; import java.

Java线程新特性--- Lock

在Java5中,专门提供了锁对象,利用锁可以方便的实现资源的封锁,用来控制对竞争资源并发访问的控制,这些内容主要集中在java.util.concurrent.locks包下面,里面有三个重要的接口Condition.Lock.ReadWriteLock. Condition Condition将Object监视器方法(wait.notify和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意Lock实现组合使用,为每个对象提供多个等待set(wait-set). Lock L

Java: 线程池(ThreadPoolExecutor)中的参数说明

最近在看<阿里巴巴Android开发手册>,里面有这样几句话: [强制]新建线程时,必须通过线程池提供(AsyncTask 或者ThreadPoolExecutor或者其他形式自定义的线程池),不允许在应用中自行显式创建线程. [强制]线程池不允许使用Executors 去创建,而是通过ThreadPoolExecutor 的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险. 个人对线程池的使用也有一段日子了,而且很多时候为了省事用的都是Executors的方式去创建

Java多线程-新特性-线程池

Sun在Java5中,对Java线程的类库做了大量的扩展,其中线程池就是Java5的新特征之一,除了线程池之外,还有很多多线程相关的内容,为多线程的编程带来了极大便利.为了编写高效稳定可靠的多线程程序,线程部分的新增内容显得尤为重要. 有关Java5线程新特征的内容全部在java.util.concurrent下面,里面包含数目众多的接口和类,熟悉这部分API特征是一项艰难的学习过程.目前有关这方面的资料和书籍都少之又少,大部分介绍线程方面书籍还停留在java5之前的知识层面上. 在Java5之

java线程详解

Java线程:概念与原理 一.操作系统中线程和进程的概念 现在的操作系统是多任务操作系统.多线程是实现多任务的一种方式. 进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程中可以启动多个线程.比如在Windows系统中,一个运行的exe就是一个进程. 线程是指进程中的一个执行流程,一个进程中可以运行多个线程.比如java.exe进程中可以运行很多线程.线程总是属于某个进程,进程中的多个线程共享进程的内存. “同时”执行是人的感觉,在线程之间实际上轮换执行. 二.Jav

Java线程详解----借鉴

Java线程:概念与原理 一.操作系统中线程和进程的概念 现在的操作系统是多任务操作系统.多线程是实现多任务的一种方式. 进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程中可以启动多个线程.比如在Windows系统中,一个运行的exe就是一个进程. 线程是指进程中的一个执行流程,一个进程中可以运行多个线程.比如java.exe进程中可以运行很多线程.线程总是属于某个进程,进程中的多个线程共享进程的内存. “同时”执行是人的感觉,在线程之间实际上轮换执行. 二.Jav

Java线程:概念与使用

Java线程大总结 原文章地址:一篇很老的专栏,但是现在看起来也感觉深受启发,知识点很多,很多线程特点我没有看,尴尬.但是还是整理了一下排版,转载一下. 操作系统中线程和进程的概念 在现代操作系统中,进程支持多线程.进程是资源管理的最小单元:线程是程序执行的最小单元. 为了实现程序的并发执行引入了进程的概念(程序段.数据段.PCB三部分).每个进程都有自己独立的一块内存空间,进程是程序的一个执行过程,进程之间可以并发执行. 线程是指进程中的一个执行流程,是CPU调度和分派的基本单位,它是比进程更

Java线程详解(三)

Java线程:新特征-有返回值的线程 在Java5之前,线程是没有返回值的,常常为了"有"返回值,破费周折,而且代码很不好写.或者干脆绕过这道坎,走别的路了. 现在Java终于有可返回值的任务(也可以叫做线程)了. 可返回值的任务必须实现Callable接口,类似的,无返回值的任务必须Runnable接口. 执行Callable任务后,可以获取一个Future的对象,在该对象上调用get就可以获取到Callable任务返回的Object了. 下面是个很简单的例子: import jav

Java多线程-新特征-阻塞队列ArrayBlockingQueue

阻塞队列是Java5线程新特征中的内容,Java定义了阻塞队列的接口java.util.concurrent.BlockingQueue,阻塞队列的概念是,一个指定长度的队列,如果队列满了,添加新元素的操作会被阻塞等待,直到有空位为止.同样,当队列为空时候,请求队列元素的操作同样会阻塞等待,直到有可用元素为止. 有了这样的功能,就为多线程的排队等候的模型实现开辟了便捷通道,非常有用. java.util.concurrent.BlockingQueue继承了java.util.Queue接口,可