用CountDownLatch實現在走完10個線程之後再進行操作

    在上一篇博客中,我們用Callable實現了這個功能:用Callable實現在走完10個線程之後再進行操作,其中也提到了使用CountDownLatch實現是一個更好地選擇,下面,我們就來看看如何使用用CountDownLatch實現在走完10個線程之後再進行操作。                                                                                                                                                                                         我們先來看看《JAVA編程思想第四版》中對CountDownLatch的描述:

	CountDownLatch被用來同步一個或多個任務,強制它們等待由其他任務執行的一組操作完成。
	你可以向CcountDownLatch對象設置一個初始計數值,任何在這個對象上調用wait的方法都將阻塞,直至這個計數值到達0。
其他任務在結束其工作時,可以再該對象上調用countDown()來減小這個計數值。CountDownLatch被設計爲只觸發一次,計數值
不能被重置。如果你需要能夠重置計數值的版本,則可以使用CyclicBarrier。
	調用countDown()的任務在產生這個調用時並沒有被阻塞只有對await()的調用會被阻塞,直到計數值到達0.
	CountDownLatch的典型用法是將一個程序分爲n個互相獨立的可解決的任務,並創建值爲0的CountDownLatch。(此處
應該是創建值爲n的CountDownLatch)當每個任務完成時,都會在這個鎖存器上調用countDown()。等待問題唄解決的
任務在這個鎖存器上調用await(),將他們自己攔住,直到鎖存器上技術結束。

再來看看具體要求的具體應用:

/**
 * 2018-05-05
 * @author liujie
 *
 */
public class TestCountDownLatch {
	public static void main(String[] args) throws Exception{
		int SIZE = 10;
		CountDownLatch latch = new CountDownLatch(SIZE);
		ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
		List<Runnable> threads = new ArrayList<Runnable>();
		for (int i = 0; i < SIZE; i++) {
			//多個任務線程共享一個CountDownLatch實例
			threads.add(new MyThread(latch));
		}
		for (Runnable runnable : threads) {
			Thread.sleep(50);
			cachedThreadPool.execute(runnable);
		}
		System.out.println("main Thread finished starting threads--" 
		+ new Date().getSeconds());
		//主線程會在這裏等待,直到latch計數值到達0
		latch.await();
		//當latch計數值到達0,說明任務線程都完成了各自任務,主線程繼續往下
		System.out.println("main Thread go on working--" + new Date().getSeconds());
	}
}
class MyThread implements Runnable{
	private CountDownLatch latch;
	private static transient int count = 0;
	private static Random random = new Random();
	private int id = count ++;
	public MyThread(CountDownLatch latch) {
		this.latch = latch;
	}
	public void run() {
		int workTimeSeconds = random.nextInt(10) + 1;
		System.out.println("Thread-" + id + "\tstart running for " 
		+ workTimeSeconds + " seconds--" + new Date().getSeconds());
		try {
			Thread.sleep(1000 * workTimeSeconds);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		//在完成自己的任務後,將latch的計數值減一
		latch.countDown();
	}
}

以下是控制檯的打印:

Thread-2	start running for 8 seconds--41
Thread-1	start running for 2 seconds--41
Thread-3	start running for 3 seconds--41
Thread-0	start running for 5 seconds--41
Thread-4	start running for 2 seconds--41
Thread-5	start running for 6 seconds--41
Thread-6	start running for 4 seconds--42
Thread-7	start running for 9 seconds--42
Thread-8	start running for 4 seconds--42
main Thread finished starting threads--42
Thread-9	start running for 1 seconds--42
main Thread go on working--51

由運行結果可知,程序實現了完成了題目的要求,主線程在第51秒的時候繼續下面的任務,這是因爲任務線程7是最後一個完成的任務(第42秒開始,耗時9秒,在51秒時完成).

我對CountDownLatch的理解:

    就相當於一個組長,在接到一個任務以後,將任務分爲N份,並在一個任務計數器開啓N個亮燈進行記錄(new CountDownLath(N)),然後將這N份任務交給N個組員去完成(threadPool開啓N個線程)。每個組員在接到任務後就各自忙自己的,在完成了他們的任務以後,就在任務計數器上熄滅一個燈(latch.countDown()),提示已經完成了自己的任務。有需要的人就會對這個任務計數器進行監控(latch.await()),直到所有的等都熄滅了,纔會繼續工作。

    


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章