`
woxiaoe
  • 浏览: 283536 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

Java线程学习笔记(十)CountDownLatch 和CyclicBarrier

    博客分类:
  • Java
阅读更多

CountDownLatch

一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。
用给定的计数 初始化 CountDownLatch。由于调用了 countDown()
方法,所以在当前计数到达零之前,await
方法会一直受阻塞。之后,会释放所有等待的线程,await
的所有后续调用都将立即返回。这种现象只出现一次——计数无法被重置。

 

CountDownLatch 很适合用来将一个任务分为n个独立的部分,等这些部分都完成后继续接下来的任务,CountDownLatch 只能出发一次,计数值不能被重置。

CyclicBarrier:

一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。

CyclicBarrier可以多次重复使用

 

下面是两个例子,一个为基于CountDownLatch 的模拟项目,一个项目可以分为多个模块,只有但这些模块都完成后才可以继续下一步的工作。

一个为基于CyclicBarrier的接力赛模拟,有四个队员,当跑完后报出最终成绩。

 

 

package com.woxiaoe.study.thread;

import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * 模拟项目的开发,只有当每个模块都完成后,项目才完成
 * 每个模块的用时不同
 * @author 小e
 *
 * 2010-4-30 下午07:41:37
 */
class Module implements Runnable{
	private CountDownLatch latch;
	private String moduleName;
	private int time;//用时
	
	

	public Module(CountDownLatch latch, String moduleName,int time) {
		super();
		this.latch = latch;
		this.moduleName = moduleName;
		this.time = time;
	}



	@Override
	public void run() {
		try {
			work();
			latch.countDown();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	private void work() throws InterruptedException{
		TimeUnit.MILLISECONDS.sleep(time);
		System.out.println(moduleName + " 完成,耗时:" + time);
	}
}
class Controller implements Runnable{
	private CountDownLatch latch;

	public Controller(CountDownLatch latch) {
		super();
		this.latch = latch;
	}

	@Override
	public void run() {
		try {
			latch.await();
			System.out.println("所有模块都完成,任务完成");
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
}
public class Project {
	static final int SIZE = 20;
	public static void main(String[] args) {
		CountDownLatch latch = new CountDownLatch(SIZE);
		Random r = new Random();
		ExecutorService exec = Executors.newCachedThreadPool();
		Controller controller = new Controller(latch);
		exec.execute(controller);
		for(int i = 0; i < SIZE; i++){
			exec.execute(new Module(latch, "模块" + (i + 1), r.nextInt(2000)));
		}
		
		exec.shutdown();
		
	}

}

 

 Output:

模块4 完成,耗时:108 模块10 完成,耗时:123 模块7 完成,耗时:136 模块19 完成,耗时:235 模块5 完成,耗时:475 模块11 完成,耗时:653 模块1 完成,耗时:745 模块2 完成,耗时:826 模块20 完成,耗时:1030 模块16 完成,耗时:1151 模块3 完成,耗时:1204 模块15 完成,耗时:1219 模块13 完成,耗时:1274 模块17 完成,耗时:1337 模块8 完成,耗时:1366 模块6 完成,耗时:1491 模块14 完成,耗时:1739 模块18 完成,耗时:1766 模块12 完成,耗时:1883 模块9 完成,耗时:1951 所有模块都完成,任务完成

 

package com.woxiaoe.study.thread;

import java.util.Random;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * 用java模拟4X100接力赛
 * 当结束后 报成绩,应用CyclicBarrier
 * @author 小e
 *
 * 2010-4-30 下午08:13:40
 */
class Player implements Runnable{
	private String name;
	private CyclicBarrier barrier;
	private Player next;//下一棒
	private int time;//用时
	private boolean run;//第一棒
	public Player(String name, CyclicBarrier barrier, boolean run) {
		super();
		this.name = name;
		this.barrier = barrier;
		this.run = run;
	}
	@Override
	public void run() {
		try {
			synchronized (this) {
				while(!run){//等待队员
					wait();
				}
			}
			Random r = new Random();
			TimeUnit.MILLISECONDS.sleep(r.nextInt(2000));
			next(next,11 + r.nextInt(2));
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
	}
	private void next(Player next, int time) {
		System.out.println(name + " 用时:" + time + ",交接棒");
		if(next != null){
			next.setTime(this.time + time);
			synchronized (next) {
				next.setRun(true);
				next.notify();
			}
		}else{
			System.out.println("跑完,总用时:" + (this.time + time));
		}
	}
	public void setTime(int time) {
		this.time = time;
	}
	public int getTime(){
		return this.time;
	}
	public void setNext(Player next) {
		this.next = next;
	}
	public void setRun(boolean run) {
		this.run = run;
	}
	
}
public class RelayRace {
	
	public static void main(String[] args) throws InterruptedException {
		final Player[] players = new Player[4];
		ExecutorService exec = Executors.newCachedThreadPool();
		CyclicBarrier barrier = new CyclicBarrier(4, new Runnable() {
			
			@Override
			public void run() {
				System.out.println("结束,总用时:" + players[3].getTime());
			}
		});
		for(int i = 0; i < 4; i++){
			players[i] = new Player("队员" + ( i + 1), barrier, i == 0);
		}
		for(int i = 0; i < 4; i++){
			if( i < 3){
				players[i].setNext(players[i + 1]);
				exec.execute(players[i]);
			}else{
				exec.execute(players[3]);
				break;
			}
		}
		/*TimeUnit.SECONDS.sleep(3);
		 * CyclicBarrier 可以重用
		for(int i = 0; i < 4; i++){
			if( i < 3){
				players[i].setNext(players[i + 1]);
				exec.execute(players[i]);
			}else{
				exec.execute(players[3]);
				break;
			}
		}*/
	}

}
 Output:
队员1 用时:11,交接棒 队员2 用时:11,交接棒 队员3 用时:11,交接棒 队员4 用时:12,交接棒 跑完,总用时:45

 


  • src.rar (2.1 KB)
  • 下载次数: 155
分享到:
评论
4 楼 jiefei_download 2011-03-29  
jiefei_download 写道
yiyidog125 写道
CyclicBarrier你传进去根本没用啊

对啊!
既然你用了concurrent包,为什么还要调用wait()?

此贴还被投了“良好贴”?
3 楼 jiefei_download 2011-03-29  
yiyidog125 写道
CyclicBarrier你传进去根本没用啊

对啊!
既然你用了concurrent包,为什么还要调用wait()?
2 楼 yiyidog125 2010-10-30  
CyclicBarrier你传进去根本没用啊
1 楼 hardPass 2010-07-14  
说白了

CountDownLatch: 一个或者是一部分线程 ,等待另外一部线程都完成了,再继续执行
CyclicBarrier: 所有线程互相等待完成。

我觉得楼主的CyclicBarrier的例子不太好,如果目的是讲CyclicBarrier的话,不如讲4个人一起跑,等4个人都跑到终点了,才可以去吃饭……

package com.wl.test.concurrent.cyclicbarrier;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 
 * @author HardPass
 * 
 */
public class CyclicBarrierTest_RelayRace {

	public static void main(String[] args) throws InterruptedException {
		ExecutorService exec = Executors.newCachedThreadPool();		
		final CyclicBarrier barrier = new CyclicBarrier(4, new Runnable() {

			@Override
			public void run() {
				System.out.println("好了,大家可以去吃饭了……"  );
			}
		});		
		
		System.out.println("要吃饭,必须所有人都到终点,oK?");				
		System.out.println("不放弃不抛弃!");
		
		for (int i = 0; i < 4; i++) {
			exec.execute(new Runnable() {

				@Override
				public void run() {
					System.out
							.println(Thread.currentThread().getName() + ":Go");
					try {
						Thread.sleep((long) (2000 * Math.random()));
					} catch (InterruptedException e1) {
						e1.printStackTrace();
					}
					System.out.println(Thread.currentThread().getName()
							+ ":我到终点了");
					try {
						barrier.await();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (BrokenBarrierException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}

					System.out.println(Thread.currentThread().getName()
							+ ":终于可以吃饭啦!");

				}
			});

		}
		exec.shutdown();
				
	}
	
	

}



相关推荐

    JAVA 多线程学习笔记

    这篇学习笔记将深入探讨Java多线程的核心概念、实现方式以及相关工具的使用。 一、多线程基础 1. 线程与进程:在操作系统中,进程是资源分配的基本单位,而线程是程序执行的基本单位。每个进程至少有一个主线程,...

    java多线程学习笔记

    - **CountDownLatch/CyclicBarrier/Semaphore**:高级并发工具类,用于协调多线程之间的协作。 5. **线程优先级** - Java线程有10个优先级,从MIN_PRIORITY(1)到MAX_PRIORITY(10),默认优先级是NORM_PRIORITY...

    Java基础尚硅谷宋红康学习笔记

    10. **Java并发编程**:包括线程池、锁机制(如synchronized、ReentrantLock)、并发容器(如ConcurrentHashMap、CopyOnWriteArrayList)以及并发工具类(如CountDownLatch、CyclicBarrier)。 这些是Java基础知识...

    java多线程笔记全手打

    本笔记全面涵盖了多线程的学习,包括基础理论和实践代码,旨在帮助开发者深入理解并掌握Java多线程技术。 一、线程基础知识 线程是操作系统分配CPU时间的基本单位,一个进程中可以包含多个线程。Java通过`Thread`类...

    Java多线程源码笔记.pdf

    9. 线程常用的工具栏:Java提供了一些并发工具类,如CountDownLatch、CyclicBarrier和Semaphore。CountDownLatch可以用于计数,等待某个任务完成;CyclicBarrier用于一组线程相互等待至某个条件达成;Semaphore则...

    java分布式应用学习笔记05多线程下的并发同步器.pdf

    7. **并发工具类**:如CountDownLatch、CyclicBarrier、Semaphore等,它们在多线程协作中起到计数器、栅栏、信号量的作用,帮助控制线程的执行顺序和数量。 了解了这些基础工具后,我们需要掌握如何根据实际情况...

    Java并发编程学习笔记

    CountDownLatch用于一次性让多个线程等待,CyclicBarrier则允许一组线程等待直到所有线程到达屏障点后一起继续执行,Semaphore管理有限资源的访问权限。 6. **线程池原理**: 线程池通过预先创建一组线程,复用...

    《Java JDK 6 学习笔记》配书示例

    12. **并发工具类(java.util.concurrent)**:包含如Semaphore、CountDownLatch、CyclicBarrier等高级并发控制工具,便于开发多线程应用。 通过《Java JDK 6 学习笔记》中的示例,读者可以深入了解这些特性,并...

    Java并发编程学习笔记.rar

    为了解决多个线程间的竞态条件,Java提供了多种同步机制,如`synchronized`关键字、`Lock`接口(包括`ReentrantLock`)以及`java.util.concurrent`包中的各种工具类,如`Semaphore`、`CountDownLatch`和`...

    Java多线程详解(超详细)_狂神说笔记完整版_项目代码_适合小白随课程学习

    - `CyclicBarrier`和`CountDownLatch`:用于线程同步,协调多个线程同时开始或结束操作。 了解并熟练掌握这些知识点,你就能在实际开发中灵活运用Java的多线程特性,编写出高效、稳定的并发程序。通过实践和不断...

    JUC学习笔记(Java多线程)

    总的来说,JUC学习笔记涵盖了Java多线程编程的主要方面,包括线程的创建与管理、同步机制、并发容器以及协调工具的使用,这些都是提升Java并发编程能力的关键知识点。通过深入理解和熟练应用这些工具,开发者可以更...

    java多线程代码笔记

    Java的`java.util.concurrent`包提供了更高级的并发工具,如`Semaphore`(信号量)、`CyclicBarrier`(循环屏障)、`CountDownLatch`(计数门锁)和`ExecutorService`。例如,`ExecutorService`可以管理和控制线程池...

    张孝祥Java多线程与并发库高级应用笔记

    - **高级特性**:包括`ExecutorService`、`Future`、`Semaphore`、`CountDownLatch`、`CyclicBarrier`、`Exchanger`等工具,提供了更灵活、强大的线程调度和控制机制。 - **优势**:减少线程管理的复杂度,提高线程...

    Java分布式应用学习笔记03JVM对线程的资源同步和交互机制

    ### Java分布式应用学习笔记03:JVM对线程的资源同步和交互机制 在深入探讨Java虚拟机(JVM)如何处理线程间的资源同步与交互机制之前,我们先来明确几个关键概念:线程、多线程、同步、并发以及它们在Java中的实现...

    java学习笔记,好好学习

    这篇“java学习笔记”可能包含了从基础到进阶的各种Java编程概念和技术。以下是对这些笔记可能涵盖的一些关键知识点的详细说明: 1. **Java基础知识**: - **语法**:包括变量声明、数据类型(如整型、浮点型、...

    Java线程系列操作.zip

    - **并发工具类**:如CountDownLatch、CyclicBarrier、Semaphore等,帮助解决多线程编程中的特定问题。 通过对这些示例代码的学习,我们可以深入理解Java线程的创建、管理、同步以及并发编程中的最佳实践,从而...

    【学习笔记】JUC基础基础程序

    本学习笔记将深入探讨JUC的基础知识,帮助你理解和掌握Java并发编程的核心概念。 在Java中,多线程是实现并发的主要方式。一个线程是程序执行的一个流,多线程则意味着一个程序内可以同时执行多个线程。Java提供了...

    java学习笔记4

    Java以其强大的并发处理能力闻名,这部分可能会讲解线程的创建(通过`Thread`类或实现`Runnable`接口)、线程同步(synchronized关键字,wait()和notify()方法)、线程池(ExecutorService)以及并发工具类(如...

    java学习笔记-老师的课程笔记

    Java学习笔记是初学者探索Java编程世界的宝贵资源。这份由老师精心整理的课程笔记涵盖了Java的基础到进阶知识,旨在帮助新手快速理解并掌握这门强大的面向对象编程语言。笔记内容可能包括但不限于以下方面: 一、...

Global site tag (gtag.js) - Google Analytics