`
Mojarra
  • 浏览: 131119 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

Java并发编程(三) CyclicBarrier

    博客分类:
  • JDK
阅读更多

在上两回中,用CountDownLatch可以很好的让4个工人等待轮胎运送到工作间合适的位置后再进行轮胎装配工作,装配完4个轮子后,4个工人用减少CountDownLatch计算器数值的方式告诉生产线,这辆汽车的轮子已经装配好。可是,你有没有发现,在我们的程序中,这4个工人只装配了一辆汽车,假如这个4个工人一天只装配一辆汽车,而你是老板的话,你可以解雇这4个工人,工厂不需要生产效率这样低下的劳动者。现在,工厂需要4个工人一天必须装配完100辆汽车的轮胎。4个工人说,这不是我们的问题,流水线上只有一辆汽车可以装配。那么,作为管理方,有办法重新设计流水线的作业方式,让4个工人舒舒服服的在一天之内安装100辆车的轮胎吗?答案是肯定的,我们有办法!于是我们重新设计流水线的作业方式。

 

流水线作业新方式

  1. 当工人们就位后,流水线上已经有一辆车放在他们的作业区,轮胎也被放置到作业区合适的位置,让工人很舒服的安装
  2. 当4个工人安装好这辆车的4个轮胎后,工人们可以进入短暂的等待状态,等待下一辆汽车被放到作业区
  3. 下一辆等待装配轮胎的汽车进入作业区。
  4. 四个新的轮胎进入作业区内放置轮胎的位置。
  5. 步骤3和步骤4准备好后,工人们可以进行装配轮胎的工作。
  6. 4个工人和流水线配合,在一天内,重复3,4和5这三个步骤,直到100辆汽车的轮胎安装完成。

 

CyclicBarrier

通过观察流水线新的作业方式,我们知道,使用CountDownLatch已经不能适应新作业方式的需求。不过,CyclicBarrier类很有信心保证能完成控制流水线的工作。它可以让每个受它监视的线程只要进入等待状态后,自身启动一个动作,用于执行一些特定任务,这个动作执行完后,线程又进入运行状态。如此循环,直到整个工作完成。

CyclicBarrier有两个构造函数。

  1. CyclicBarrier(int) 用于构造一个CyclicBarrier实例,参数int表示在这个CyclicBarrier上等待的线程的数量。
  2. CyclicBarrier(int, Runnable) 用于构造一个带Runnable接口的实例,第一个int参数与第一种构造函数中的参数意义相同,runnable接口代表一个要执行的动作,这个动作在受到CyclicBarrier实例监视的所有线程都处于等待状态时执行。如果用第一种构造函数,则这些线程处于等待状态时,什么动作也不执行。

FullTimeWorker

现在这4个工人不再是上一回中,1天只能装配1个轮胎的工人了,他们有能力在一天之内装配100个轮胎,因此,我们称它们为全职工人,在FullTimeWorker线程中,当前的WorkSpace中的车辆已经放置好,工人拿到一个轮胎,安装上后,处于等待下一辆车和轮胎被放到工作区。FullTimeWorker线程中,如果捕捉到BrokenBarrierException,表示当前的流水线控制系统有问题,则会停止当前的工作,另外3个FullTimeWorker线程也会停止工作,整个装配工作将停止。

 

@Override
	public void run() {
		for (int i = 0; i < 100; i++) {
			try {
				Tyre tyre = tyries.take();  //拿到一个轮胎
				Car car = workspace.getCar();   //当前作业区中的车辆

//我开始进行装配工作
 System.out.format("%s is assembling the %s for the %s.%n", name, tyre, car);
				marshalTyre();
				System.out.format("%s has assembled the %s for the %s.%n", name, tyre, car);

				// 我的轮胎装配完了,等待下一辆车和轮胎被送入我的作业区。				
				barrier.await();

			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (BrokenBarrierException e) {
				e.printStackTrace();
				return;
			}
		}
		System.out.format("%s has done work of the day%n", name);
	}
 

AssemblyLine

AssemblyLine类是这个流水线上的控制程序,当CyclicBarrier锁发现这4个工人都处于等待状态时,控制流水线把下一辆车和4个新的轮胎送入这4个工人的作业区。让这个4个工作有事可做,而不是一直处于等待状态。

AssemblyLine必须实现Runnable接口。显然,运送轮胎和车的工作必须放在run方法中实现。

static class AssemblyLine implements Runnable {
		static int tyreNo = 0;
		ArrayBlockingQueue<Car> cars;

		@Override
		public void run() {
			try {
				Car car = null;
				if (!cars.isEmpty()) {
					car = cars.take();
					workspace.setCar(car);  // 把下一辆车放入作业区
					prepareTyre();                // 把4个轮胎放入作业区
					System.out.format("-------------- a new %s and four tyres are ready --------------%n", car);
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

		public AssemblyLine(ArrayBlockingQueue<Car> cars) {
			this.cars = cars;
		}

		private static void prepareTyre() throws InterruptedException {
			for (int i = 0; i < 4; i++) {
				tyries.offer(new Tyre(tyreNo++));
				Thread.sleep(500);
			}
		}
	}

 

运行

到目前为止,流水线作业方式已经重新设计过,工人也有能力一天安装100个轮胎,流水线运送也有能力自动的根据工人的状态来运送车辆和轮胎,所有的一切都已经具备,就等按下总开关,让整条流水线开始运作起来。

首先,准备好100辆车可供流水线可调配。

ArrayBlockingQueue<Car> cars = new ArrayBlockingQueue<Car>(100);
		for (int i = 0; i < 100; i++)
			cars.offer(new Car(i));

 

接着把工人们放到流水线位置,让CyclicBarrier作为流水线控制系统,协调工人与流水线的工作,这里有一点小小的注意,在工人们开始工作之前,流水线先放一辆车和4个轮胎到工作区。

CyclicBarrier barrier = new CyclicBarrier(4, new AssemblyLine(cars));

		AssemblyLine.prepareTyre();
		workspace.setCar(cars.take());

 

接着,工人们开始干活了,流水线也可以运转了。

ExecutorService executorService = Executors.newFixedThreadPool(4);
		String works[] = { "John Chembers", "Bill Gates", "Larry Page", "Ericsson Limited" };
		for (int i = 0; i < 4; i++)
			executorService.execute(new FullTimeWorker(works[i], barrier));

		executorService.shutdown();

 

小结

在一个CyclicBarrier监视下的所有线程都处于等待状态时,CyclicBarrier可以执行一个特定的动作。这个动作执行完后,线程继续运行。如果让最后一个进入等待的线程干一个特定的动作,可以在线程的run方法内进行判断,下面的代码假设CyclicBarrier实例共监视着4个线程

if (barrier.await() == 4) {
// some action...
}
 

如果任何一个被监视的线程在等待是发生了任何异常,所有其它的线程也会抛出同样的异常。在FullTimeWorker的run方法中,如果捕捉到了InterruptedException,其他的三个线程也会抛出InterruptedException。

 

最后,完整的代码在附近中,欢迎下载测试,并告诉我您所发现的bug.

 

[原创内容,版权所有,如有转载,请注明出处,如有错误之处,请指出,不胜感激]

 

 

 

 

1
3
分享到:
评论

相关推荐

    《java 并发编程实战高清PDF版》

    《Java并发编程实战》是一本深入探讨Java平台并发编程的权威指南。这本书旨在帮助开发者理解和掌握在Java环境中创建高效、可扩展且可靠的多线程应用程序的关键技术和实践。它涵盖了从基本概念到高级主题的广泛内容,...

    java并发编程艺术

    《Java并发编程艺术》这本书深入探讨了Java平台上的并发编程技术。并发编程是现代多核处理器环境下提升软件性能的关键手段,而Java语言提供了丰富的工具和API来支持这一领域。本书旨在帮助开发者理解和掌握如何在...

    java并发编程2

    Java并发编程是Java开发中的重要领域,特别是在多核处理器和分布式系统中,高效地利用并发可以极大地提升程序的性能和响应速度。以下是对标题和描述中所提及的几个知识点的详细解释: 1. **线程与并发** - **线程*...

    Java 并发编程实战.pdf

    根据提供的信息,“Java 并发编程实战.pdf”这本书聚焦于Java并发编程的实践与应用,旨在帮助读者深入了解并掌握Java中的多线程技术及其在实际项目中的应用技巧。虽然部分内容未能提供具体章节或实例,但从标题及...

    java 并发编程的艺术pdf清晰完整版 源码

    《Java并发编程的艺术》这本书是Java开发者深入理解并发编程的重要参考书籍。这本书全面地介绍了Java平台上的并发和多线程编程技术,旨在帮助开发者解决在实际工作中遇到的并发问题,提高程序的性能和可伸缩性。 ...

    Java并发编程实践高清pdf及源码

    《Java并发编程实践》是一本深入探讨Java多线程编程的经典著作,由Brian Goetz、Tim Peierls、Joshua Bloch、Joseph Bowles和David Holmes等专家共同编写。这本书全面介绍了Java平台上的并发编程技术,是Java开发...

    JAVA并发编程艺术pdf版

    《JAVA并发编程艺术》是Java开发者深入理解和掌握并发编程的一本重要著作,它涵盖了Java并发领域的核心概念和技术。这本书详细阐述了如何在多线程环境下有效地编写高效、可靠的代码,对于提升Java程序员的技能水平...

    Java并发编程从入门到精通(pdf)(附源码)

    《Java并发编程从入门到精通》是一本专为Java开发者设计的深度学习并发编程的书籍。作者韩剑锋,凭借其12年的IT行业经验,曾担任多家IT公司的研发总监和技术总监,以其丰富的实战经验和深厚的理论知识,为读者提供了...

    java并发编程实践pdf笔记

    Java并发编程实践是Java开发中不可或缺的一个领域,它涉及到如何高效、正确地处理多线程环境中的任务。这本书的读书笔记涵盖了多个关键知识点,旨在帮助读者深入理解Java并发编程的核心概念。 1. **线程和进程的...

    Java并发编程(CyclicBarrier)实例详解

    Java并发编程(CyclicBarrier)实例详解 Java并发编程(CyclicBarrier)实例详解主要介绍了Java并发编程(CyclicBarrier)实例详解的相关资料,JAVA编写并发程序的时候,我们需要仔细去思考一下并发流程的控制,...

    java并发编程与实践

    "Java并发编程与实践"文档深入剖析了这一主题,旨在帮助开发者理解和掌握如何在Java环境中有效地实现并发。 并发是指在单个执行单元(如CPU)中同时执行两个或更多任务的能力。在Java中,这主要通过线程来实现,...

    Java并发编程实践.pdf

    ### Java并发编程实践 #### 一、并发编程基础 ##### 1.1 并发与并行的区别 在Java并发编程中,首先需要理解“并发”(Concurrency)和“并行”(Parallelism)的区别。“并发”指的是多个任务在同一时间段内交替...

    java并发编程

    Java并发编程是Java开发者必须掌握的关键技能之一,它涉及到如何在多线程环境中高效、安全地执行程序。并发编程能够充分利用多核处理器的计算能力,提高应用程序的响应速度和整体性能。《Java编程并发实战》这本书是...

    Java并发编程-3.pdf

    Java并发编程中的多线程协作机制 在 Java 并发编程中,多线程协作机制是非常重要的一部分。多线程协作机制是指在多线程编程中,多个线程之间如何协作、同步和通信,以达到共同完成某个任务的目的。Java 提供了多种...

    JAVA并发编程实践 中文 高清 带书签 完整版 Doug Lea .pdf

    根据提供的文件信息,“JAVA并发编程实践 中文 高清 带书签 完整版 Doug Lea .pdf”,我们可以推断出这份文档主要聚焦于Java并发编程的技术实践与理论探讨。下面将从多个角度来解析这个文档可能涵盖的关键知识点。 ...

    Java并发编程设计原则和模式

    本资料“Java并发编程设计原则和模式”深入探讨了如何在Java环境中有效地进行并发处理,以充分利用系统资源并避免潜在的并发问题。 一、并发编程基础 并发是指两个或多个操作在同一时间段内执行,但并不意味着这些...

    Java并发编程从入门到精通源码.rar

    Java并发编程是Java开发中的重要领域,特别是在大型分布式系统、多线程应用和服务器端程序设计中不可或缺。这个资源包“Java并发编程从入门到精通源码.rar”显然是为了帮助开发者深入理解并掌握这一关键技能。它包含...

    java并发编程实战高清版pdf

    《Java并发编程实战》是Java开发者深入理解和掌握并发编程的一本经典著作。这本书全面地介绍了Java平台上的并发和多线程编程技术,旨在帮助开发者在多核时代编写出高效、可伸缩且线程安全的代码。 并发编程是现代...

    Java并发编程常识-梁飞.rar

    Java并发编程是Java开发中的重要领域,特别是在多核处理器和分布式系统中,高效地利用并发可以极大地提升程序的性能和响应速度。阿里大牛梁飞编写的《Java并发编程常识》PPT,深入浅出地讲解了这个主题,对开发者来...

    Java并发编程相关资料

    Java并发编程是Java开发中的重要领域,涉及到多线程、同步机制、线程池等多个核心概念,对于构建高效、稳定的应用至关重要。这份资料包含了关于Java并发编程的博客和网页,可以提供深入的理解和实践指导。 在Java...

Global site tag (gtag.js) - Google Analytics