1. 程式人生 > >假如有Thread1、Thread2、Thread3三條執行緒分別統計C、D、E三個盤的大小,所有執行緒都統計完畢交給Thread4執行緒去做彙總

假如有Thread1、Thread2、Thread3三條執行緒分別統計C、D、E三個盤的大小,所有執行緒都統計完畢交給Thread4執行緒去做彙總

如題:

有三種解決方法

第一種是實現callable方法,重寫call方法

http://blog.csdn.net/silyvin/article/details/79235111

我個人不想用這個方法,所以只貼了連結

第二種方法:join方法

建立3個執行緒

Runnable r1 = new ThreadUtils("A");
Runnable r2 = new ThreadUtils("B");
Runnable r3 = new ThreadUtils("C");
Thread thread1 = new Thread(r1);
Thread thread2 = new Thread(r2);
Thread thread3 = new 
Thread(r3);
thread1.start();thread2.start();thread3.start();

在三個執行緒就緒之後,採用join()方法加入到主執行緒

thread1.join();
thread2.join();
thread3.join();

由於join()方法的機制是:當有一個新執行緒請求加入時,當前執行緒阻塞,join()內部利用的wait方法,直到新執行緒執行完畢後,才notifyAll喚醒了主執行緒,所以這樣當三個執行緒依次加入後,結果必定是3個執行緒都已經統計完畢,但是有個缺點,這有點違背了3個執行緒併發的初衷,現在成了序列執行。

第三種利用了java.util.concurrent下的CountDownLatch類

CountDownLatch :一個執行緒(或者多個), 等待另外N個執行緒完成某個事情之後才能執行

CountDownLatch 是計數器, 執行緒完成一個就記一個, 就像 報數一樣, 只不過是遞減的.

CountDownLatch countDownLatch = new CountDownLatch(3);//3個執行緒協同工作
Runnable r1 = new ThreadUtils("A",countDownLatch);
Runnable r2 = new ThreadUtils("B",countDownLatch);
Runnable r3 = new ThreadUtils("C"
,countDownLatch); Thread thread1 = new Thread(r1); Thread thread2 = new Thread(r2); Thread thread3 = new Thread(r3); thread1.start(); thread2.start(); countDownLatch.await(); System.out.println("完畢"); thread3.start();
public class ThreadUtils implements Runnable{
    CountDownLatch countDownLatch = null;
    private String name=null;
    public ThreadUtils(String name){
        this.name = name;
}

    public ThreadUtils(String a, CountDownLatch countDownLatch) {
        this.name = a;
        this.countDownLatch = countDownLatch;
}

    public void run(){
        if (name.equals("C")){
            System.out.println(name+"彙總完畢");
}else {
            doWork(name);
System.out.println(name+"統計結束");
}
        countDownLatch.countDown();//每當完成一個計數器減掉1
}
    private void doWork(String name){
        System.out.println(name+"正在統計盤子大小....");
}
}

此方法可以滿足其它執行緒併發的需求,更加契合題意。

CyclicBarrier        : N個執行緒相互等待,任何一個執行緒完成之前,所有的執行緒都必須等待。
這樣應該就清楚一點了,對於CountDownLatch來說,重點是那個“一個執行緒”, 是它在等待, 而另外那N的執行緒在把“某個事情”做完之後可以繼續等待,可以終止。而對於CyclicBarrier來說,重點是那N個執行緒,他們之間任何一個沒有完成,所有的執行緒都必須等待。

CyclicBarrier更像一個水閘, 執行緒執行就想水流, 在水閘處都會堵住, 等到水滿(執行緒到齊)了, 才開始洩流.

http://blog.csdn.net/silyvin/article/details/79235111