假如有Thread1Thread2ThreaD3Thread4四条线程分别统计CDEF四个盘的大小,所有线程都统计完毕交给Thread5线程去做汇总,应当如何实现?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了假如有Thread1Thread2ThreaD3Thread4四条线程分别统计CDEF四个盘的大小,所有线程都统计完毕交给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.           
  14.         // 添加结束,及时shutdown,不然主线程不会结束  
  15.         es.shutdown();  
  16.           
  17.         int total = 0;  
  18.         for(int i=0;i<4;i++){  
  19.             try {  
  20.                 total+=cs.take().get();  
  21.             } catch (InterruptedException e) {  
  22.                 e.printStackTrace();  
  23.             } catch (ExecutionException e) {  
  24.                 e.printStackTrace();  
  25.             }  
  26.         }  
  27.           
  28.         System.out.println(total);  
  29.     }  
  30. }  
  31.   
  32. class ThreadCount implements Callable<Integer>{  
  33.     private int type;  
  34.     ThreadCount(int type){  
  35.         this.type = type;  
  36.     }  
  37.     @Override  
  38.     public Integer call() throws Exception {  
  39.         if(type==1){  
  40.             System.out.println("C盘统计大小");  
  41.             return 1;  
  42.         }else if(type==2){  
  43.             Thread.sleep(20000);  
  44.             System.out.println("D盘统计大小");  
  45.             return 2;  
  46.         }else if(type==3){  
  47.             System.out.println("E盘统计大小");  
  48.             return 3;  
  49.         }else if(type==4){  
  50.             System.out.println("F盘统计大小");  
  51.             return 4;  
  52.         }  
  53.         return null;  
  54.     }  
  55. }  

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.           
  13.           
  14.     static class Worker extends Thread{      
  15.         String workerName;       
  16.         int workTime;      
  17.         CountDownLatch latch;      
  18.         public Worker(String workerName ,int workTime ,CountDownLatch latch){      
  19.              this.workerName=workerName;      
  20.              this.workTime=workTime;      
  21.              this.latch=latch;      
  22.         }      
  23.         public void run(){      
  24.             System.out.println("Worker "+workerName+" do work begin at "+sdf.format(new Date()));      
  25.             doWork();//工作了      
  26.             System.out.println("Worker "+workerName+" do work complete at "+sdf.format(new Date()));      
  27.             latch.countDown();//工人完成工作,计数器减一      
  28.       
  29.         }      
  30.               
  31.         private void doWork(){      
  32.             try {      
  33.                 Thread.sleep(workTime);      
  34.             } catch (InterruptedException e) {      
  35.                 e.printStackTrace();      
  36.             }      
  37.         }      
  38.     }      
  39.           
  40.            
  41. }   

 

 

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

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

以上是关于假如有Thread1Thread2ThreaD3Thread4四条线程分别统计CDEF四个盘的大小,所有线程都统计完毕交给Thread5线程去做汇总,应当如何实现?的主要内容,如果未能解决你的问题,请参考以下文章

假如我年少有为不自卑

假如一个程序员有"社交牛逼症"

假如有一个2500 万行的开源项目,你敢动么?

假如习惯成自然

假如有一天,人工智能用于相亲

论假如有一台无限算力的主机