天天看點

CountDownLatch--一組線程完成後其他線程才執行(一)問題背景:

問題背景:

問題一:

java多線程,A、B、C、D統計4個盤大小,統計完後第5個人彙總。

問題二:

比如一個團隊賽跑遊戲,最後要計算團隊賽跑的成績,主線程計算最後成績,要等到所有團隊成員跑完,方可計算總成績。

java.util.concurrent.CountDownLatch

你可以向 CountDownLatch 對象設定一個初始計數值,任何在這個對象上調用  await()  的方法都将阻塞,直到這個計數值為0。其他任務在結束其工作時,可以在該對象上調用 countDown() 來減小這個數值,這個方法不會阻塞線程。 CountDownLatch 被設計為隻觸發一次,計數值不能被重置。如果你需要能夠重置計數值的版本,則可以使用 CyclicBarrier .

 CountDownLatch  的典型用法時将一個程式分成n個互相獨立的可解決任務,并建立值為n的CountDownLatch。每當任務完成時,都會在這個鎖存儲器上調用countDown()方法。等待問題被解決的任務在這個鎖存儲器上調用await()。将它們自己攔住,直到存儲器計數結束。

示例1:通用代碼示例

import java.util.concurrent.CountDownLatch;

/**
 * 比如一個團隊賽跑遊戲,最後要計算團隊賽跑的成績,主線程計算最後成績,要等到所有
 * 團隊成員跑完,方可計算總成績。
 * 
 * 題目2:統計4個盤子的大小,統計完後交給第五個人彙總
 */
public class CountDownLatchTest {
	public static void main(String[] args) throws InterruptedException {
		CountDownLatch startSignal = new CountDownLatch(1);
		CountDownLatch doneSignal = new CountDownLatch(4);
		
		
		//四個人賽跑,這4個可以寫一個for循環
		new Thread(new Worker(startSignal, doneSignal)).start();
		new Thread(new Worker(startSignal, doneSignal)).start();
		new Thread(new Worker(startSignal, doneSignal)).start();
		new Thread(new Worker(startSignal, doneSignal)).start();

		System.out.println("這裡放計數前自己的代碼...");//由于startSignal是1,上邊的4個線程還不能執行
		startSignal.countDown(); // startSignal=0,線程可以開始執行了
		
		//doSomethingElse();
		System.out.println("計數後的代碼...這是主線程...和上邊4個線程混在一起的...");
		doneSignal.await(); // 判斷上邊4個是否執行完了,如果是,則允許下邊的代碼執行
		//開始執行另外一個任務
		System.out.println("開始執行其他任務...");
	}
}
           
class Worker implements Runnable {
	private final CountDownLatch startSignal;
	private final CountDownLatch doneSignal;

	Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
		this.startSignal = startSignal;
		this.doneSignal = doneSignal;
	}

	@Override
	public void run() {
		try {
			startSignal.await();  //startSignal的計數到0了嗎?到0了,才能執行
			doWork();
			doneSignal.countDown();
		} catch (InterruptedException ex) {
		} 
	}

	void doWork() {
		System.out.println("正在統計中...");
	}
}
           
//結果
這裡放計數前自己的代碼...
計數後的代碼...這是主線程...和上邊4個線程混在一起的...
正在統計中...
正在統計中...
正在統計中...
正在統計中...
開始執行其他任務...
           

繼續閱讀