`
suhuanzheng7784877
  • 浏览: 702423 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
Ff8d036b-05a9-33b5-828a-2633bb68b7e6
读金庸故事,品程序人生
浏览量:47707
社区版块
存档分类
最新评论

Java分布式应用学习笔记05多线程下的并发同步器----后篇

阅读更多

5.  CountDownLatch

很多资料上都说CountDownLatch是倒数计数器,我觉得这种说法太过专业,其实它就是一个数数的人员。利用它,可以在多线程执行任务完毕后完成进行多线程的等待,便于等待所有的线程之后在干别的事情,这个有点类似于FutureTask,使用上不太一样。这个场景就是一个线程必须要等到其他线程执行完毕后才能往下执行,注意,这里这个线程没必要需要其他线程的执行结果,而是只有一个条件就是其他线程必须执行完毕。咱们依然做个比喻,韦小宝需要8部《四十二章经》才能去鹿鼎山找寻宝藏,怎么办,他有7个老婆,不能资源浪费啊,这个任务同时进行吧。咱们设计8个线程同时进行,等所有老婆都执行完毕了,每个老婆找齐了《四十二章经》了,好了,他可以自己去找宝藏了。等等,咱们小宝哥有7个老婆,何来8个线程,这个问题,读者不必较真,举个例子罢了,咱们给他加个老婆不就行了!

代码如下

package threadConcurrent.test;

import java.util.concurrent.CountDownLatch;

/**
 * 分部执行任务
 * 
 * @author liuyan
 * 
 */
public class CountDownLatchDemo implements Runnable {
	private int id;

	// 线程之间不影响,到了终点后继续做自己的事情
	private CountDownLatch countDownLatch;

	public CountDownLatchDemo(int id, CountDownLatch countDownLatch) {
		this.id = id;
		this.countDownLatch = countDownLatch;
	}

	@SuppressWarnings("static-access")
	@Override
	public void run() {
		try {

			System.out.println("第" + (id + 1) + "小老婆开始查找《四十二章经》...");
			Thread.currentThread().sleep(id * 1000);
			System.out.println("第" + (id + 1) + "本《四十二章经》找到");

			//计数器将等待数字-1
			countDownLatch.countDown();

			System.out.println("第" + (id + 1) + "小老婆继续干其他事情");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		CountDownLatch countDownLatch = new CountDownLatch(8);

		for (int i = 0; i < 8; i++) {
			new Thread(new CountDownLatchDemo(i, countDownLatch)).start();
		}

		try {

			System.out.println("韦小宝等着等着8本四十二章……");

			// 韦小宝等着等着
			countDownLatch.await();

			// 等待运动员到达终点
			System.out.println("8本四十二章经找寻完成,可以寻宝了!");
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

 

主线程就当做是韦小宝吧,主线程首先开辟了线程计数器对象,之后就开辟了8个线程,派出了8个小老婆去办事,之后主线程调用countDownLatch.await()阻塞,在家里一直喝着小茶,听着小曲等着8个线程的执行完毕。咱们来看小老婆们,小老婆们就辛苦了,开始找寻经书,之后调用countDownLatch.countDown()方法通知线程计数器减去1,让等待的线程减去1。就好比说有个小老婆找到了《四十二章经》,用iphone发个彩信将经书的夹缝地图发给韦小宝,韦小宝收到了,恩,这个老婆能干,任务完成,我的等待目标减去1。等到等待线程为0的时候,小宝开始行动了,将手机里的地图通过游戏——拼图游戏,一拼凑,大事可成,自己寻宝去!这里大家也看到了CountDownLatchFutureTask的区别。CountDownLatch侧重的是分线程的完成个数,每次完成一个分线程,等待数目减少一个,等待线程为0的时候,主线程的就不阻塞了,开始往下走。而分线程一旦调用countDownLatch.countDown()方法,就代表分线程任务搞定,主线程就不会因为你的其他事情而不能往下走,完成任务了,小老婆们也可以去旅旅游,休息休息!而FutureTask则是注重执行结果的,主线程需要它的确切结果。所以futureTask执行的call()有返回值。

6.  CyclicBarrier

CyclicBarrier相对于CountDownLatch来说,最大的不同是,分线程具体的执行过程受其他分线程的影响,必须每个分线程都执行完毕了,主线程才继续往下走,而分线程如果在所有分线程执行完毕后还有其他动作,ok,还你自由,不必阻塞了,往下走你的路吧。这个例子是网上的游戏玩家的例子,4个小孩玩游戏,游戏要求必须是4个小孩都得通过第一关,才能开启第二关的关口!否则其他完成第一关的人都得等着其他人完成。这个有点像我们的项目开发,分模块开发,到一定阶段将模块汇总,联调,测试,如果这时候有一个模块没完成,大家等着吧,大家都在那里静静地、盯着你、等着你。

package threadConcurrent.test;

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

public class GameBarrier {
	public static void main(String[] args) {
		CyclicBarrier cyclicBarrier = new CyclicBarrier(4, new Runnable() {

			@Override
			public void run() {
				System.out.println("所有玩家进入第二关!");
			}
		});

		for (int i = 0; i < 4; i++) {
			new Thread(new Player(i, cyclicBarrier)).start();
		}
	}

}

class Player implements Runnable {
	
	/**
	 * 线程之间需要交互,到一定的条件下,所有线程才能往下走
	 */
	private CyclicBarrier cyclicBarrier;
	private int id;

	public Player(int id, CyclicBarrier cyclicBarrier) {
		this.cyclicBarrier = cyclicBarrier;
		this.id = id;
	}

	@Override
	public void run() {
		try {
			System.out.println("玩家" + id + "正在玩第一关...");
			cyclicBarrier.await();
			System.out.println("玩家" + id + "进入第二关...");
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (BrokenBarrierException e) {
			e.printStackTrace();
		}
	}
}

 使用cyclicBarrier.await();方法进行等待、阻塞,当所有分线程执行完毕了,主线程开始执行,分线程的自由也解脱了,继续往下走,开始第二关。

7.  Exchanger

Exchanger是线程资源交换器,线程A与线程B在某个运行阶段需要互换资源才能完成任务。这就好比2个公司职员——叶小钗和一页书。分别在不同的项目组——组A和组B,两个组开发者不同的项目,在正常时候叶小钗在组A上班开发者BOSS项目,一页书在项目组B开发ESB中间件产品。而在特殊时期项目组B不需要一页书了,需要叶小钗提供技术支持,就和项目组A要叶小钗,项目组Aleader也不是吃素的,你要叶小钗,没问题,把一页书也得接我们项目组剥削几天!就这样项目组B与项目组A做了这种“交易”(交换),用完了之后,恩~看程序吧

package threadConcurrent.test;

import java.util.concurrent.Exchanger;

/**
 * 资源交换
 * @author liuyan
 */
public class ExgrDemo {
	public static void main(String args[]) {
		
		//交换器
		Exchanger<String> exgr = new Exchanger<String>();

		new TeamB(exgr);
		new TeamA(exgr);
	}
}

/**
 * 项目组A
 * @author liuyan
 */
class TeamA implements Runnable {
	Exchanger<String> ex;

	String str;

	TeamA(Exchanger<String> c) {
		ex = c;
		str = new String();

		new Thread(this).start();
	}

	public void run() {
		char ch = 'A';
		for (int i = 0; i < 3; i++) {
			for (int j = 0; j < 5; j++)
				str += (char) ch++;

			try {
				str = ex.exchange(str);
			} catch (InterruptedException exc) {
				System.out.println(exc);
			}
		}
	}
}

/**
 * 项目组B
 * @author liuyan
 */
class TeamB implements Runnable {
	Exchanger<String> ex;

	String str;

	TeamB(Exchanger<String> c) {
		ex = c;
		new Thread(this).start();
	}

	public void run() {

		for (int i = 0; i < 3; i++) {
			try {
				str = ex.exchange(new String());
				System.out.println("Got: " + str);
			} catch (InterruptedException exc) {
				System.out.println(exc);
			}
		}
	}
}

 

需要说明的就是这种交换一定是成对儿的,就是交换的线程数目一定是偶数。否则奇数个线程,剩下那一个和谁交换去?这也是“等价交易”的一种体现。

8.  总结

这次主要介绍了并发环境下常常使用的并发包,用于控制多线程的并发调度、同步、交互、交换、协作等等。使用这些协作同步器,可以更灵活的处理线程之间的关系。也能更好地使用硬件资源为我们的并发系统提供高效率的运行能力。当然这次总结仅仅限于使用的层次,底层的实现源码分析有时间再做总结。

 

34
14
分享到:
评论
12 楼 ycnanevol 2012-06-21  
第五个例子似乎有些问题

这个是我的运行结果


第1小老婆开始查找《四十二章经》...
第4小老婆开始查找《四十二章经》...
第3小老婆开始查找《四十二章经》...
第2小老婆开始查找《四十二章经》...
第5小老婆开始查找《四十二章经》...
第1本《四十二章经》找到
第1小老婆继续干其他事情
第6小老婆开始查找《四十二章经》...
第7小老婆开始查找《四十二章经》...
韦小宝等着等着8本四十二章……
第8小老婆开始查找《四十二章经》...
第2本《四十二章经》找到
第2小老婆继续干其他事情
第3本《四十二章经》找到
第3小老婆继续干其他事情
第4本《四十二章经》找到
第4小老婆继续干其他事情
第5本《四十二章经》找到
第5小老婆继续干其他事情
第6本《四十二章经》找到
第6小老婆继续干其他事情
第7本《四十二章经》找到
第7小老婆继续干其他事情
第8本《四十二章经》找到
第8小老婆继续干其他事情
8本四十二章经找寻完成,可以寻宝了!

在 韦小宝等着四十二章经的之前,第一本已经找到了
11 楼 suhuanzheng7784877 2011-09-01  
buaawhl 写道



CyclicBarrier

CountDownLatch

FutureTask

这些概念都是第一次听说。我还停留在几年前的概念中。out了呀。

博主语言很出彩。



呵呵~~彼此彼此。希望有不正确的地方进行指正。
10 楼 buaawhl 2011-09-01  



CyclicBarrier

CountDownLatch

FutureTask

这些概念都是第一次听说。我还停留在几年前的概念中。out了呀。

博主语言很出彩。


9 楼 suhuanzheng7784877 2011-08-15  
1111111
??
suhuanzheng7784877 写道
引用
1111111
??


问了才知道,原来是单身~~唉~~~out了
8 楼 suhuanzheng7784877 2011-08-15  
qijinha_toni 写道
知识要是都这么直白就好了

恩,尽量……
7 楼 suhuanzheng7784877 2011-08-15  
andey007518 写道
兄弟分析的深入浅出,通俗易懂,没事多向你学习哈,

呵呵,共同学习啊~
6 楼 qijinha_toni 2011-08-13  
知识要是都这么直白就好了
5 楼 andey007518 2011-08-13  
兄弟分析的深入浅出,通俗易懂,没事多向你学习哈,
4 楼 四书五经 2011-08-12  
uuid198909 写道
博主的文笔越来越犀利了。顶,期待你的下个作品。

3 楼 suhuanzheng7784877 2011-08-11  
引用
1111111
??
2 楼 ma_xuezhi1987 2011-08-11  
引用
System.out.println("第" + (id + 1) + "小老婆开始查找《四十二章经》..."); 

把多线程比做小老婆,哈哈哈哈哈哈哈哈哈哈哈哈哈哈。可怜一下我们这些1111111吧
1 楼 uuid198909 2011-08-11  
博主的文笔越来越犀利了。顶,期待你的下个作品。

相关推荐

    巨量引擎-抖音上的80后、90后、00后 之 00后篇-2019.8-15页.pdf

    ### 巨量引擎-抖音上的80后、90后、00后 之 00后篇 #### 数据背景及方法论 本报告由巨量引擎商业算数中心出品,旨在通过分析2018年12月至2019年6月期间的数据来深入探讨抖音平台上00后用户的兴趣爱好、行为习惯...

    软件工程课程资料-后篇

    在本压缩包中,我们聚焦于“软件工程”的后篇,涵盖了从软件实现到软件维护,以及面向对象方法的相关知识。这些内容对于理解和实践软件开发过程至关重要,是软件工程课程的核心部分。 首先,"第7章 软件实现.ppt"会...

    毕业论文:光伏并网发电系统-后篇

    完整优秀的毕业论文“光伏并网发电系统”设计,当时制作出实际样品进行演示,内涵流程图\软件\算法公式、源程序设计、 ...因页数比较多,特意拆成前篇、中篇、后篇发布;需要的请下全三篇文档,保你满意!

    Deep Learning深度学习入门论文

    level Features Using Large Scale Unsupervised Learning和Large Scale Distributed Deep Networks,其中后篇较好,其中第一次提到GPU对深度学习计算进行提速,其描述的情形大致是如何对多个GPGPU并行计算的深度...

    国金证券-汽车及汽车零部件行业上海车展专题(展后篇):智能化&插混化&品牌向上,勾勒市场竞争新格局-230428.pdf

    展会规模宏大,预计参观人数较上一届增长25%,新能源车参展数量更是翻了一倍多,这充分展示了汽车行业在新能源领域的快速发展和市场需求的不断提升。 在智能化方面,各大车企纷纷展示其在智能驾驶、智能网联等方面...

    【翻译】西川善司 Child of Eden后篇1

    这种表现手法在商业游戏中并不多见,它将声音、图像和玩家交互完美融合,体现了游戏作为一种多媒体艺术的潜力。 游戏的视觉特效主要依赖于一种名为BISHAMON的3D特效插件。BISHAMON作为一个中间件,加速了游戏中的...

    【翻译】西川善司 街头霸王4图形讲座 后篇1

    在后篇中,我们深入探讨了如何在3D环境中重现2D格斗游戏的精髓和风格。游戏开发者Dimps公司在设计过程中,既追求真实感,又保留了2D像素画的特色。 首先,游戏中的角色动作并非全部依赖于动作捕捉技术,而是由艺术...

    python标准库学习(后篇)

    执行已编译的代码execfile&#40;"hello.py"&#41;defEXECFILE&#40;filename,locals=None,globals=None&#41;:execcompile(open(filename).read(),filename,"exec")inlocals,globalsEXECFILE&#40;"hello.py"&#41;...

    为了3D游戏粉丝的[(超级)街头霸王4]图形讲座(后篇)

    ### 《为了3D游戏粉丝的[(超级)街头霸王4]图形讲座(后篇)》知识点详述 #### 一、2D格斗游戏趣味的3D化 《超级街头霸王4》作为一款经典的格斗游戏,在从2D向3D过渡的过程中,不仅要保留原有的游戏性,还需要在...

    《易学C++》配套电子教案(后篇)

    其书写的思路和语言的风格受到了很多读者的肯定。 为了帮助读者更好地理解这本书,作者特意编写了配套的电子教案。生动的动画示例、有趣的课堂小测试、新鲜的教学理念又在互联网上掀起了C++的热潮。《易学C++》的...

    初中教师资格证2011教育心理学大纲整理后篇.doc

    心理发展被分为多个阶段,如童年期、少年期和青年期。青少年期(初中阶段)处于半成熟、半幼稚的过渡期,而青年期则在生理和心理上向成年期接近。 学习准备是指学生在学习新知识时的心理准备状态,关键期是个体早期...

    初中教师资格证2020教育心理学大纲整理后篇.doc

    教育心理学是研究学校环境中学习与教学基本心理规律的学科,它结合了心理学与教育学的理论,关注学生、教师、教学内容、教学媒体和教学环境等要素。教育心理学研究的核心内容包括学习过程、教学过程以及评价与反思...

    易学C++ 电子版以及源代码网络热捧

    2. **继承与多态**:如何通过继承实现代码复用,多态性(动态绑定)及其在多态基类和虚函数中的应用。 3. **模板与泛型编程**:理解模板的使用,包括函数模板和类模板,以及泛型编程的思想。 4. **STL(Standard ...

    走向ASP.NET架构设计—第四章—业务层分层架构(后篇)

     AnemicDomainModel: 这种模式和之前讲述的DomainModel有很多的相似的地方。在之前的DomainModel中,每个业务类都包含了自己的业务逻辑和数据,以及对象之前的关系;但是在AnemicDomainModel,每个业务类仅仅只是...

Global site tag (gtag.js) - Google Analytics