有两种方法:
第一种方法:
一般情况,我们实现多线程都是Thread或者Runnable(后者比较多),但是,这两种都是没返回值的,所以我们需要使用callable(有返回值的多线程)和future(获得线程的返回值)来实现了。
/**
* 假如有Thread1、Thread2、ThreaD3、Thread4四条线程分别统计C、D、E、F四个盘的大小,所有线程都统计完毕交给Thread5线程去做汇总,应当如何实现?
*/
publicclass TestThread {
publicstaticvoid main(String[] args) {
ThreadCount tc =null;
ExecutorService es = Executors.newCachedThreadPool();//线程池
CompletionService cs =new ExecutorCompletionService(es);
for(int i=0;i<4;i++){
tc =new ThreadCount(i+1);
cs.submit(tc);
}
// 添加结束,及时shutdown,不然主线程不会结束
es.shutdown();
int total =0;
for(int i=0;i<4;i++){
try {
total+=cs.take().get();
}catch (InterruptedException e) {
e.printStackTrace();
}catch (ExecutionException e) {
e.printStackTrace();
}
}
System.out.println(total);
}
}
class ThreadCountimplements Callable{
privateint type;
ThreadCount(int type){
this.type = type;
}
@Override
public Integer call()throws Exception {
if(type==1){
System.out.println("C盘统计大小");
return1;
}elseif(type==2){
Thread.sleep(20000);
System.out.println("D盘统计大小");
return2;
}elseif(type==3){
System.out.println("E盘统计大小");
return3;
}elseif(type==4){
System.out.println("F盘统计大小");
return4;
}
returnnull;
}
}
ps:一个需要注意的小细节,cs.take.get()获取返回值,是按照完成的顺序的,即上面案例返回顺序是CEFD
第二种方法:
第一种方法:
直接用join把线程5加入进去即可
第二种方法:
用Java.util.concurrent下的方法解决
用CountDownLatch : 一个线程(或者多个), 等待另外N个线程完成某个事情之后才能执行
CountDownLatch 是计数器, 线程完成一个就记一个, 就像 报数一样, 只不过是递减的.
一个例子如下:
publicclass CountDownLatchDemo {
finalstatic SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
publicstaticvoid main(String[] args)throws InterruptedException {
CountDownLatch latch=new CountDownLatch(2);//两个工人的协作
Worker worker1=new Worker("zhang san",5000, latch);
Worker worker2=new Worker("li si",8000, latch);
worker1.start();//
worker2.start();//
latch.await();//等待所有工人完成工作
System.out.println("all work done at "+sdf.format(new Date()));
}
staticclass Workerextends Thread{
String workerName;
int workTime;
CountDownLatch latch;
public Worker(String workerName ,int workTime ,CountDownLatch latch){
this.workerName=workerName;
this.workTime=workTime;
this.latch=latch;
}
publicvoid run(){
System.out.println("Worker "+workerName+" do work begin at "+sdf.format(new Date()));
doWork();//工作了
System.out.println("Worker "+workerName+" do work complete at "+sdf.format(new Date()));
latch.countDown();//工人完成工作,计数器减一
}
privatevoid doWork(){
try {
Thread.sleep(workTime);
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
CyclicBarrier : N个线程相互等待,任何一个线程完成之前,所有的线程都必须等待。
这样应该就清楚一点了,对于CountDownLatch来说,重点是那个“一个线程”, 是它在等待,
而另外那N的线程在把“某个事情”做完之后可以继续等待,可以终止。而对于CyclicBarrier来说,重点是那N个线程,他们之间任何一个没有完成,所有的线程都必须等待。CyclicBarrier更像一个水闸,
线程执行就想水流, 在水闸处都会堵住, 等到水满(线程到齐)了, 才开始泄流.