1. 程式人生 > >CountDownLatch和CyclicBarrier的區別

CountDownLatch和CyclicBarrier的區別

1. 官方概念

CyclicBarrier

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

CountDownLatch 

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

2. 個人理解

CyclicBarrier 

想想柵欄的意思,有點像切面的意思。

場景如下:

1)就比如假設有隻有的一個場景:每個執行緒代表一個跑步運動員,當運動員都準備好後,才一起出發,只要有一個人沒有準備好,大家都等待. 功能如下圖所示。

2)玩家0正在玩第一關...玩家3正在玩第一關...玩家2正在玩第一關...玩家1正在玩第一關...所有玩家進入第二關

從上面圖可以看出CyclicBarrier  也可以作為計數器用

CountDownLatch

是計數器, 執行緒完成一個就記一個, 就像 報數一樣, 只不過是遞減的. 結構/功能如下圖所示

3. 實際列子

1)需求: 有20個執行緒需要執行, 單執行緒池中最多隻能有5個執行緒執行, 需要在所有執行緒執行完之後再進行其他操作

2)需求: 將Case 自動化儲存到測試用例管理工具中,每個Case也有可能使用別的Case當做前提條件,若需要將Case儲存到TestRail 中需要以下步驟:

儲存每個Case的流程如下:

A:儲存Case的詳細資訊到testrail

B: 儲存Case的前提條件(需要其他Case的CaseID)到testrail.

C: 儲存Case的後續條件(需要其他Case的CaseID)到testrail.

這就說明。儲存Case的前提條件必須在儲存所有Case的詳細資訊以後獲取到CaseID, 再儲存前提條件到每個Case中

分析: 使用CyclicBarrier 實現

詳細程式碼如下

import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;

public class CaseToTestRail implements Runnable {
	
	private String id ;
	
	private String pre;
	
	private String name;
	
	private CyclicBarrier barrier;	
	
	 public CaseToTestRail(String name, CyclicBarrier barrier) {
	        this.name = name;
	        this.barrier = barrier;
	    }

	@Override
	public void run() {
		// TODO Auto-generated method stub
		try {
			System.out.println(name + "已準備生成TestRail case");
	
			TimeUnit.SECONDS.sleep(1 + (new Random().nextInt(5)));
			this.id = name;
			barrier.await();
			this.pre = id;
			  TimeUnit.SECONDS.sleep(1 + (new Random().nextInt(3)));
	          System.out.println(pre + "====前提條件");
	          barrier.await();
	          System.out.println(pre + "===========後續條件");
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			System.out.println("Inter e");
			e.printStackTrace();
		} catch (BrokenBarrierException e) {
			// TODO Auto-generated catch block
			System.out.println("BrokenBarrierException");
			e.printStackTrace();
		}

	}

}
public class Client {

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		List<String> list = new ArrayList<String>();
		for (int i = 1; i <= 5; i++) {
			list.add("case" + i);
		}
		ExecutorService pool = Executors.newFixedThreadPool(list.size());

		List<Runnable> runnalbes = new ArrayList<Runnable>();
		CyclicBarrier barrier = new CyclicBarrier(list.size());
		for (int i = 0; i < list.size(); i++) {
			final String caseName = list.get(i);
			CaseToTestRail runnables = new CaseToTestRail(caseName, barrier);
			runnalbes.add(runnables);
			pool.execute(runnables);
		}
		System.out.println("下一個task。。");

	}

}