CyclicBarrier學習

概述

字面意思迴環柵欄,通過它可以實現讓一組線程等待至某個狀態之後再全部同時執行。叫做迴環是因爲當所有等待線程都被釋放以後,CyclicBarrier可以被重用。我們暫且把這個狀態就叫做barrier,當調用await()方法之後,線程就處於barrier了。

package com.business.thread;

import java.util.Map;
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CyclicBarrier;

public class UseCyclicBarrier {
	static CyclicBarrier barrier = new CyclicBarrier(5, new collectThread());
	private static ConcurrentHashMap<String, Long> resultMap = new ConcurrentHashMap<String, Long>();// 存放子線程工作結果的容器

	public static void main(String[] args) {
		for (int i = 0; i <= 4; i++) {
			Thread thread = new Thread(new SubThread());
			thread.start();
		}
	}

	// 彙總線程
	private static class collectThread implements Runnable {

		public void run() {
			StringBuilder result = new StringBuilder();
			for (Map.Entry<String, Long> workResult : resultMap.entrySet()) {
				result.append("[" + workResult.getValue() + "]");
			}
			System.out.println("result :" + result);
			System.out.println("do other business");
		}
	}

	// 工作線程
	private static class SubThread implements Runnable {

		public void run() {
			long id = Thread.currentThread().getId();
			resultMap.put(id + "", id);
			Random r = new Random();

			if (r.nextBoolean()) {
				try {
					Thread.sleep((int) (1000 + id));
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println("Thread_" + id + "......do sth");
			}
			try {
				//等待collectThread線程完成
				barrier.await();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (BrokenBarrierException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			try {
				Thread.sleep((int) (1000 + id));
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println("Thread_" + id + "............do business");

		}
	}
}

執行結果:

Thread_13......do sth
result :[11][12][13][14][10]
do other business
Thread_10............do business
Thread_11............do business
Thread_12............do business
Thread_13............do business
Thread_14............do business

 

SubThread線程需要等待collectThread線程完成之後,才能繼續下面的任務。

CyclicBarrier與CountDownLatch比較

  1)CountDownLatch:一個線程(或者多個),等待另外N個線程完成某個事情之後才能執行;CyclicBarrier:N個線程相互等待,任何一個線程完成之前,所有的線程都必須等待。

  2)CountDownLatch:一次性的;CyclicBarrier:可以重複使用。

  3)CountDownLatch基於AQS;CyclicBarrier基於鎖和Condition。本質上都是依賴於volatile和CAS實現的。

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