假如有Thread1、Thread2、ThreaD3、Thread4四条线程分别统计C、D、E、F四个盘的大小,所有线程都统计完毕交给Thread5线程去做汇总,应当如何实现?

有两种方法:

  第一种方法:

一般情况,我们实现多线程都是Thread或者Runnable(后者比较多),但是,这两种都是没返回值的,所以我们需要使用callable(有返回值的多线程)和future(获得线程的返回值)来实现了。

  1. /**
  2. * 假如有Thread1、Thread2、ThreaD3、Thread4四条线程分别统计C、D、E、F四个盘的大小,所有线程都统计完毕交给Thread5线程去做汇总,应当如何实现?
  3. */
  4. public class TestThread {
  5. public static void main(String[] args) {
  6. ThreadCount tc = null;
  7. ExecutorService es = Executors.newCachedThreadPool();//线程池
  8. CompletionService<Integer> cs = new ExecutorCompletionService<Integer>(es);
  9. for(int i=0;i<4;i++){
  10. tc = new ThreadCount(i+1);
  11. cs.submit(tc);
  12. }
  13. // 添加结束,及时shutdown,不然主线程不会结束
  14. es.shutdown();
  15. int total = 0;
  16. for(int i=0;i<4;i++){
  17. try {
  18. total+=cs.take().get();
  19. } catch (InterruptedException e) {
  20. e.printStackTrace();
  21. } catch (ExecutionException e) {
  22. e.printStackTrace();
  23. }
  24. }
  25. System.out.println(total);
  26. }
  27. }
  28. class ThreadCount implements Callable<Integer>{
  29. private int type;
  30. ThreadCount(int type){
  31. this.type = type;
  32. }
  33. @Override
  34. public Integer call() throws Exception {
  35. if(type==1){
  36. System.out.println("C盘统计大小");
  37. return 1;
  38. }else if(type==2){
  39. Thread.sleep(20000);
  40. System.out.println("D盘统计大小");
  41. return 2;
  42. }else if(type==3){
  43. System.out.println("E盘统计大小");
  44. return 3;
  45. }else if(type==4){
  46. System.out.println("F盘统计大小");
  47. return 4;
  48. }
  49. return null;
  50. }
  51. }

ps:一个需要注意的小细节,cs.take.get()获取返回值,是按照完成的顺序的,即上面案例返回顺序是CEFD

 第二种方法:

第一种方法:

直接用join把线程5加入进去即可

第二种方法:

Java.util.concurrent下的方法解决

用CountDownLatch : 一个线程(或者多个), 等待另外N个线程完成某个事情之后才能执行

CountDownLatch 是计数器, 线程完成一个就记一个, 就像 报数一样, 只不过是递减的.

一个例子如下:

  1. public class CountDownLatchDemo {
  2. final static SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  3. public static void main(String[] args) throws InterruptedException {
  4. CountDownLatch latch=new CountDownLatch(2);//两个工人的协作
  5. Worker worker1=new Worker("zhang san", 5000, latch);
  6. Worker worker2=new Worker("li si", 8000, latch);
  7. worker1.start();//
  8. worker2.start();//
  9. latch.await();//等待所有工人完成工作
  10. System.out.println("all work done at "+sdf.format(new Date()));
  11. }
  12. static class Worker extends Thread{
  13. String workerName;
  14. int workTime;
  15. CountDownLatch latch;
  16. public Worker(String workerName ,int workTime ,CountDownLatch latch){
  17. this.workerName=workerName;
  18. this.workTime=workTime;
  19. this.latch=latch;
  20. }
  21. public void run(){
  22. System.out.println("Worker "+workerName+" do work begin at "+sdf.format(new Date()));
  23. doWork();//工作了
  24. System.out.println("Worker "+workerName+" do work complete at "+sdf.format(new Date()));
  25. latch.countDown();//工人完成工作,计数器减一
  26. }
  27. private void doWork(){
  28. try {
  29. Thread.sleep(workTime);
  30. } catch (InterruptedException e) {
  31. e.printStackTrace();
  32. }
  33. }
  34. }
  35. }

CyclicBarrier        : N个线程相互等待,任何一个线程完成之前,所有的线程都必须等待。

这样应该就清楚一点了,对于CountDownLatch来说,重点是那个“一个线程”, 是它在等待, 而另外那N的线程在把“某个事情”做完之后可以继续等待,可以终止。而对于CyclicBarrier来说,重点是那N个线程,他们之间任何一个没有完成,所有的线程都必须等待。CyclicBarrier更像一个水闸, 线程执行就想水流, 在水闸处都会堵住, 等到水满(线程到齐)了, 才开始泄流.

时间: 2024-11-09 10:50:01

假如有Thread1、Thread2、ThreaD3、Thread4四条线程分别统计C、D、E、F四个盘的大小,所有线程都统计完毕交给Thread5线程去做汇总,应当如何实现?的相关文章

有Thread1、Thread2、Thread3、Thread4四条线程分别统计C、D、E、F四个盘的大小,所有线程都统计完毕交给Thread5线程去做汇总,应当如何实现?

利用java.util.concurrent包下的CountDownLatch(数降闩)或CyclicBarrier(循环屏障) 转自:http://www.cnblogs.com/westward/p/7144620.html

Python之路(第四十二篇)线程相关的其他方法、join()、Thread类的start()和run()方法的区别、守护线程

一.线程相关的其他方法 Thread实例对象的方法 # isAlive(): 返回线程是否活动的. # getName(): 返回线程名. # setName(): 设置线程名. ? threading模块提供的一些方法: # threading.currentThread(): 返回当前的线程对象. # threading.enumerate(): 返回一个包含正在运行的线程的list.正在运行指线程启动后.结束前,不包括启动前和终止后的线程. # threading.activeCount(

设计测试用例的四条原则

今天是2011年的第一天,2010年就这样匆匆忙忙,紧紧张张地过去了.这一年里来来去去,变化最大的就是很多一起工作了多年的同事离开了,很多都去了"更给力”的地方,呵呵!公司里来来往往是很正常的,想想我最近一次换到“更给力”的地方,那都是5年前了.总之,现在的地方还是挺给力的,好好工作,争取2011年有更大的进步,呱唧呱唧! 测试用例设计的最基本要求:覆盖住所要测试的功能.这是再基本不过的要求了,但别看只是简单的一句话,要能够达到切实覆盖全面,需要对被测试产品功能的全面了解.明确测试范围(特别是要

四条地铁线带你通往Ajax的大门

Ajax,国内翻译为"阿贾克斯",一开始听到这个名字的时候就给我一种高大上的感觉,确实,现在只要是比较大型的网站,都用到了Ajax,对于一个前端开发者而言,不会使用Ajax,基本上就失去了很多优势,因为只要是大型的公司,基本都是要前后端进行交互,Ajax扮演了一个相当于月老的作用,将前端后台进行完美结合,所以,掌握Ajax,对于一个前端开发者而言是必不可少的.当然那些立志于只做网页重构的,只在公司负责将UI的图还原出来的人,可以忽视此篇文章. Ajax,比较官方的说法是:"通

Effective Objective-C 2.0 — 第四条:多用类型常量,少用#define预处理指令

第四条:多用类型常量,少用#define预处理指令 使用#define 预处理的坏处:定义出来的常量没有类型信息,编译器只是会在编译前据此执行查找与替换操作.即使有人重新定义了常量值,编译器也不会产生警告信息,这将导致应用程序中的常量值不一致. 使用例如:static const NSTimeInterval kAnimationDuration = 0.3; 在实现文件中使用 static const 来定义“只在编译单元内可见的常量”.由于此类常量不再全局符号表中,所以无须为其名称加前缀.

雅虎十四条 - 14个优化网站性能提高网站访问速度的技巧

14个优化网站性能提高网站访问速度的技巧 又叫“雅虎十四条”,想起一年前那个懵懂的我,大四傻乎乎的跑到大学城面试前端,那个时候以为寒暑假看了两套CSS的视频,就很牛B了,出发先还把视频温了一下,嗯嗯,这是滑动门,嗯嗯这是绝对定位,嗯嗯这是浮动清除…… 当时是彪叔面试我的,当时我还不知道那个人,全身黑漆漆的,黑色T-shirt,黑色皮肤,黑色帽子,黑色墨镜,还有点黑色胡渣的人,就是彪叔,补做了试题后支支吾吾的跟他谈了一下,发现完全不行,第一个问题是“雅虎十四条”是什么?然后我蒙了,pardon?

请对照这二十四条逻辑谬误自行打脸(转自知乎谢熊猫专栏)

[科普工具文]请对照这二十四条逻辑谬误自行打脸 谢熊猫君 · 1 年前 两年前,我还活跃在人人网的时候,曾经整理过一篇常见逻辑谬误的工具文,用来帮助大家在网络讨论中打脸用: [科普工具文]请对照这二十四条逻辑谬误自行打脸 这两年来在一些社交网站和互联网论坛中常看到有人使用这篇文章,想来也是有点用处的,特意在这边转帖一下,为方便各位在知乎讨论时能更加方便的辨别逻辑问题. ======================= ======================= 本文内容基本都来自于英文网站ht

第四条:通过私有构造器强化不可实例化的能力

我们在开发中经常会去做一些工具类,这些类中的方法和变量都是static的.而这样的工具类是不希望呗实例化的.然后我们知道jdk会在无构造器的时候,自动的提供一个无参数的缺省构造器.该构造器就会提供给用户一个创建改类对象的接口,因而我们在工具类中会将此构造函数显示化私有化: public class UtilityClass{ private UtilityClass(){ // 用来避免在类内不小心的调用该构造器 throw new AssertError(); } ...... } 该条建议,

【tool】设计测试用例的四条原则

测试用例设计的最基本要求:覆盖住所要测试的功能.这是再基本不过的要求了,但别看只是简单的一句话,要能够达到切实覆盖全面,需要对被测试产品功能的全面了解.明确测试范围(特别是要明确哪些是不需要测试的).具备基本的测试技术(如:等价类划分等)等.那么满足了上述这条要求是不是设计出来的测试用例就是好的测试用例了呢?答案:在理论上是,但在实际工程中还远远不是.之所以理论和实际会有这样的差别,是因为在理论上不要考虑 测试用例设计的最基本要求:覆盖住所要测试的功能.这是再基本不过的要求了,但别看只是简单的一