美文网首页
12. 假如有Thread1、Thread2、ThreaD3、T

12. 假如有Thread1、Thread2、ThreaD3、T

作者: 木有鱼丸啦 | 来源:发表于2018-03-02 13:54 被阅读0次

有两种方法:

第一种方法:

  一般情况,我们实现多线程都是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更像一个水闸,

线程执行就想水流, 在水闸处都会堵住, 等到水满(线程到齐)了, 才开始泄流.

相关文章

网友评论

      本文标题:12. 假如有Thread1、Thread2、ThreaD3、T

      本文链接:https://www.haomeiwen.com/subject/igtdxftx.html