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

Java并发编程(一) CountDownLatch

    博客分类:
  • JDK
阅读更多

介绍

CountDownLatch是JDK5引入的一个新的线程辅助类,用于帮助开发人员”比较精确"的控制线程状态。CountDownLatch这个类内置了一个锁计数器,这个计数器由新建这个类的实例时指定,每调用countDown()方法一次,计数器的数字减一,当计数器为零时,所有的等待线程被释放并执行,否则这些线程是处于等待状态。

 

这个类在两种典型的场合下可以用得到。

 

第一种场合是若干个线程必须等待一个事件或者一些动作发生后才开始执行。比如,博尔特和其他7位在百米赛场上的选手必须等到发令枪响后才可以起跑,最后一位选手冲过终点时,百米跑比赛结束。这种情况下需要用参数1来初始化。

 

第二种场合是某件事情或者动作必须等到所有的线程都执行完后才发生执行。比如装配汽车的时候,4个工人装配4个轮子,只有4个轮子都被安装好后,流水线才能让这辆汽车进入下一个装配环节。这种情况下,用参数4来初始化。当然,这种情况,也可以用CyclicBarrier类来控制。

 

百米飞人大战

首先用代码模拟第一种场合。在Player类中有一个锁,让运动员处于等待状态。只有等一声发令枪响后,运动员才可以起跑。latch.await()方法正是起到了这个效果。Player中run1私有函数让线程休眠10秒钟内的一个随即时间,模拟运动员在跑的过程中,跑完后,运动员抵达终点。

 

在main函数中,新建一个CountDownLatch,并且设置计算器为1。接着新建一个可以同时运行8个线程的线程池-- 模拟赛道,通过调用ExecuteService.execute()函数,让所有的运动员都进入这个赛道。这个时候,计数器的值为1,所有的线程是处于等待状态。OK,接下来,调用latch.countDown(),让锁计数器为零。ExecutorService中的8个线程同时启动,所有的运动员起跑。 最后,ExecutorService.shutdown()函数会等待线程池中的8个线程全部执行完后,关闭线程池,--- 比赛结束。

class Player implements Runnable {
	private String name;
	private CountDownLatch latch;

	public Player(String name, CountDownLatch latch) {
		super();
		this.name = name;
		this.latch = latch;
	}

	@Override
	public void run() {
		try {
			latch.await();
			run1();
			System.out.format("Player %s reaches the endponit.%n", name);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private void run1() throws InterruptedException {
		Thread.sleep(new Random().nextInt(10000));
	}

	public static void main(String args[]) {
		CountDownLatch latch = new CountDownLatch(1);
		ExecutorService executor = Executors.newFixedThreadPool(8);
		String players[] = { "Bolt", "Robles", "Liu Xiang", "Johnson", "Louis", "Gatlin", "Green", "Robert" };
		for (int i = 0; i < 8; i++)
			executor.execute(new Player(players[i], latch));
		latch.countDown();
		executor.shutdown();
	}
} 

 

装配汽车轮子

假设有4个工人在汽车生产流水线上同时装配一辆汽车上的4个轮子,因为每个工人装配轮子的速度会不一样,在汽车进入下一个作业环节前,生产流水线必须知道这辆汽车的4个轮子已经被装配好。首先设置计算器为4, 当一个工人把轮子装好后,按下按钮,让计数器减一,计数器的值变成3,最后,4个工人全部按下按钮后,计数器的值变成零。一旦计数器为零,生产线的控制程序让这辆车,进入下一个装配作业环节。

先看一下Worker类,代表一个可以安装车轮的工人,为了能明确的表示一个车轮,这里车轮被抽象成一个数字,用id代表。Worker.run()方法调用marshalTyre()私有成员函数 ------代表装配轮子,只不过是让该线程休眠了60s内的一个随机时间。实际上,该方法是主要的业务代码,完成了轮子的装配工作。当工人完成自己的工作后,调用latch.countDown()方法,按下计算器按钮,告诉生产线控制中心,表示我已经完成了按照轮子的任务。哈,我可以去喝口水了。

 

再看一下main函数中的latch.await()这行,表示,流水线一直在等待计数器被清零。当计算器为零后,可以统计这次装配用的整时间啦。

 

public class Worker implements Runnable {
	private int id;
	private CountDownLatch latch;

	public Worker(int id, CountDownLatch latch) {
		this.id = id;
		this.latch = latch;
	}

	@Override
	public void run() {
		try {
			System.out.format("tyre %d is assembling.%n", id);
			marshalTyre();
			System.out.format("tyre %d is assembled.%n", id);
			latch.countDown();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

	}

	private void marshalTyre() throws InterruptedException {
		Thread.sleep(new Random().nextInt(60000));
	}

	/**
	 * @param args
	 * @throws InterruptedException
	 */
	public static void main(String[] args) throws InterruptedException {
		CountDownLatch latch = new CountDownLatch(4);
		ExecutorService executor = Executors.newFixedThreadPool(4);
		long s = System.currentTimeMillis();
		for (int i = 0; i < 4; i++)
			executor.execute(new Worker(i, latch));
		latch.await();
		System.out.format("the 4 tyres were assembled. costs %d ms.%n", System.currentTimeMillis() - s);
		executor.shutdown();
	}
}

 

好了,我们对这个例子进行拓展,工人在装配轮胎之前,轮胎必须是已经放到了合适的位置,假如这辆车到达的时候,轮胎还没有准备好,那么必须等到轮胎准备就绪后才可以开始安装工作。换住话说,轮胎没有准备好,工人就一直处于等待“轮胎就绪”这个事件上。当轮胎准备好后,才可以安装。这种情况下,需要用到两把CountDownLatch。具体怎么用,下次再写。

 

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

2
1
分享到:
评论

相关推荐

    Java并发编程一CountDownLatch、CyclicBarrier、Semaphore初使用

    Java并发编程一CountDownLatch、CyclicBarrier、Semaphore初使用 CountDownLatch、CyclicBarrier、Semaphore这些线程协作工具类是基于AQS的,看完这篇博客后可以去看下面这篇博客,了解它们是如何实现的。 Java并发...

    java并发编程中CountDownLatch和CyclicBarrier的使用借鉴.pdf

    java并发编程中CountDownLatch和CyclicBarrier的使用借鉴.pdf

    java并发编程中CountDownLatch和CyclicBarrier的使用.pdf

    java并发编程中CountDownLatch和CyclicBarrier的使用.pdf

    Java并发编程:CountDownLatch与CyclicBarrier和Semaphore的实例详解

    主要介绍了Java并发编程:CountDownLatch与CyclicBarrier和Semaphore的实例详解的相关资料,需要的朋友可以参考下

    Java并发编程学习笔记

    7、并发工具类CountDownLatch 、CyclicBarrier和Semaphore底层实现原理 8、线程池原理和如何使用线程池 9、ThreadLocal 为什么会内存泄漏 10、Volatile底层实现原理 11、AQS源码分析 12、CAS原理分析和使用场景 13、...

    Java并发编程原理与实战

    并发工具类CountDownLatch详解.mp4 并发工具类CyclicBarrier 详解.mp4 并发工具类Semaphore详解.mp4 并发工具类Exchanger详解.mp4 CountDownLatch,CyclicBarrier,Semaphore源码解析.mp4 提前完成任务之FutureTask...

    龙果 java并发编程原理实战

    龙果 java并发编程原理实战 第2节理解多线程与并发的之间的联系与区别 [免费观看] 00:11:59分钟 | 第3节解析多线程与多进程的联系以及上下文切换所导致资源浪费问题 [免费观看] 00:13:03分钟 | 第4节学习并发的四...

    Java并发编程基础.pdf

    Java并发编程基础主要包括以下几个核心方面: 线程与线程状态:理解Java中线程的基本概念,包括线程的创建、启动、暂停、恢复和终止。熟悉线程的生命周期及其不同状态,如新建、就绪、运行、阻塞和死亡。 线程同步...

    龙果java并发编程完整视频

    第37节并发工具类CountDownLatch详解00:22:04分钟 | 第38节并发工具类CyclicBarrier 详解00:11:52分钟 | 第39节并发工具类Semaphore详解00:17:27分钟 | 第40节并发工具类Exchanger详解00:13:47分钟 | 第41节...

    汪文君高并发编程实战视频资源下载.txt

    │ Java并发编程.png │ ppt+源码.rar │ 高并发编程第二阶段01讲、课程大纲及主要内容介绍.wmv │ 高并发编程第二阶段02讲、介绍四种Singleton方式的优缺点在多线程情况下.wmv │ 高并发编程第二阶段03讲、...

    Java并发编程相关技术使用案例

    1、本资源包含并发编程基础知识的使用案例,包括:线程创建、Synchronized和Reentrantlock锁的使用、线程安全问题演示、Condition的应用、CountDownLatch的应用、Cyclicbarrier的应用、Semaphore的应用、线程池的...

    Java 并发编程原理与实战视频

    java并发编程原理实战 第2节理解多线程与并发的之间的联系与区别 [免费观看] 00:11:59分钟 | 第3节解析多线程与多进程的联系以及上下文切换所导致资源浪费问题 [免费观看] 00:13:03分钟 | 第4节学习并发的四个...

    Java并发编程实战

    Java并发编程实战 本书深入浅出地介绍了Java线程和并发,是一本完美的Java并发参考手册。书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险、构造线程安全的类及...

    Java并发编程(学习笔记).xmind

    Java并发编程 背景介绍 并发历史 必要性 进程 资源分配的最小单位 线程 CPU调度的最小单位 线程的优势 (1)如果设计正确,多线程程序可以通过提高处理器资源的利用率来提升系统吞吐率 ...

    java并发编程三剑客

    目录java并发编程三剑客思维导图CountDownLatch用法构造器以及方法构造器主要方法使用方法CyclicBarrier用法构造器以及主要方法构造器主要方法使用方法Semaphore用法构造器和主要方法构造器主要方法使用方法三种辅助...

    汪文君高并发编程实战视频资源全集

    │ Java并发编程.png │ ppt+源码.rar │ 高并发编程第二阶段01讲、课程大纲及主要内容介绍.wmv │ 高并发编程第二阶段02讲、介绍四种Singleton方式的优缺点在多线程情况下.wmv │ 高并发编程第二阶段03讲、...

    并发编程面试专题.pdf

    6)用 Java 编程一个会导致死锁的程序,你将怎么解决? 7) 什么是原子操作,Java 中的原子操作是什么? 8) Java 中的 volatile 关键是什么作用?怎样使用它?在 Java 中它跟 synchronized 方法有什么不同? 9) 什么...

    java并发编程框架.pdf

    countdownlatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完毕再执行。从命名可以解读到countdown是倒数的意思,类似于我们倒计时的概念。 countdownlatch提供了两个方法,一个是...

    java并发编程

    第37节并发工具类CountDownLatch详解00:22:04分钟 | 第38节并发工具类CyclicBarrier 详解00:11:52分钟 | 第39节并发工具类Semaphore详解00:17:27分钟 | 第40节并发工具类Exchanger详解00:13:47分钟 | 第41节...

Global site tag (gtag.js) - Google Analytics