1. 程式人生 > >閉鎖CountDownLatch和柵欄CyclicBarrier之異同舉例

閉鎖CountDownLatch和柵欄CyclicBarrier之異同舉例

CountDownLatch和CyclicBarrier的主要聯絡和區別如下:
1.閉鎖CountDownLatch做減計數,而柵欄CyclicBarrier則是加計數。
2.CountDownLatch是一次性的,CyclicBarrier可以重用。
3.CountDownLatch強調一個執行緒等多個執行緒完成某件事情。CyclicBarrier是多個執行緒互等,等大家都完成。
4.鑑於上面的描述,CyclicBarrier在一些場景中可以替代CountDownLatch實現類似的功能。

另外,值得一提的是,CountDownLatch和CyclicBarrier在建立和啟動執行緒時,都沒有明確提到同時啟動全部執行緒,事實上這在技術上是不大可能,不必要,不提倡的。

先看例子一:
class SubRunnable implements Runnable {
	private CountDownLatch begin, end;
	private List<Integer> sublist;
	
	public SubRunnable(List<Integer> sublist, CountDownLatch begin,CountDownLatch end) {
		this.sublist = sublist;
		
		this.begin = begin;
		this.end = end;
	}
	
	@Override
	public void run() {
		try {
			begin.await();			
			
			if (sublist != null) {
				for (int i : sublist) {
					System.out.println("執行緒" + Thread.currentThread().getName() + ", i = " + i);
				}
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally{
			System.out.println(System.currentTimeMillis() + ",執行緒" + Thread.currentThread().getName() + ",開始執行!");
			end.countDown();
		}
	}
}

public class BatchWithCountDownLatch {
	private static final int MAX = 3;
	
	private static void list(List<Integer> list) {
		if(list == null){
			list = new ArrayList<Integer>();
		}
		
		for(int i = 0 ;i < 1000;i++){
			list.add(i);
		}
	}

	public static void main(String[] args) {
		List<Integer> list = new ArrayList<Integer>();
		list(list);
		
		//把list拆分成多個
		int mod = list.size() % MAX;
		int threadCount = mod == 0 ? list.size() / MAX : list.size() / MAX + 1;
		ExecutorService executors = Executors.newFixedThreadPool(threadCount);
		
		CountDownLatch begin = new CountDownLatch(1); 
		CountDownLatch end = new CountDownLatch(threadCount); 
				
		for(int i = 0; i< threadCount;i++){
			int subsize = (i + 1) * MAX;
			executors.execute(new SubRunnable(list.subList(i * MAX, subsize > list.size() ? list.size() : subsize),begin,end));
		}
		
		System.out.println("開始 !");
		begin.countDown();
		long startTime = System.currentTimeMillis();
		
		try {
			end.await();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			System.out.println("執行緒" + Thread.currentThread().getName() + "," + System.currentTimeMillis() + ", 所有執行緒已完成,開始進入下一步!");
			System.out.println("花費時間 -> " + (System.currentTimeMillis() - startTime) + " ms");
		}
		
		System.out.println("開始進入第二步操作! ");		
		
		System.out.println("end! ");
	}
}
這是根據jdk文件中的虛擬碼例程,編寫的一個例子,我們完全可以將這個例程改為只使用一個CountDownLatch來實現之。經過測試,發現begin的引入對程式基本無用,當list是1000的數量級時,最先啟動的執行緒仍然比最後啟動的快幾十毫秒左右;而不設定begin開始閉鎖的程式,也是完全一樣的情況。

例子二:
class SubRunnable implements Runnable {
    private CyclicBarrier cyclicBarrier;
    private List<Integer> sublist;
    
    public SubRunnable(List<Integer> sublist, CyclicBarrier cyclicBarrier) {
        this.sublist = sublist;
        this.cyclicBarrier = cyclicBarrier;
    }
    
    @Override
    public void run() {        
        try {
            System.out.println(System.currentTimeMillis() + ",執行緒" + Thread.currentThread().getName() + ",開始執行!");
            if(sublist != null){
                for(int i : sublist){
                    System.out.println("執行緒" + Thread.currentThread().getName() + ", i = " + i);
                }
            }

            cyclicBarrier.await();
        } catch (InterruptedException | BrokenBarrierException e) {
            e.printStackTrace();
        }
    }    
}

public class ReplaceCountDownLatch {
    private static final int MAX = 3;
    
    private static void list(List<Integer> list) {
        if(list == null){
            list = new ArrayList<Integer>();
        }
        
        for(int i = 0 ;i < 10;i++){
            list.add(i);
        }
    }
    
    public static void main(String[] args) throws InterruptedException, BrokenBarrierException {
        List<Integer> list = new ArrayList<Integer>();
        list(list);

        //把list拆分成多個
        int mod = list.size() % MAX;
        int threadCount = mod == 0 ? list.size() / MAX : list.size() / MAX + 1;
        ExecutorService executors = Executors.newFixedThreadPool(threadCount);

        final CyclicBarrier cyclicBarrier = new CyclicBarrier(threadCount,new Runnable() {
            @Override
            public void run() {
                //根據jdkdoc裡的描述,哪個執行緒最後執行完,就執行下面的程式碼。
                System.out.println("執行緒" + Thread.currentThread().getName() + "," + System.currentTimeMillis() + ", 所有執行緒已完成,開始進入下一步!");
            }
        });
        
        for(int i = 0; i< threadCount;i++){
            int subsize = (i + 1) * MAX;
            executors.execute(new SubRunnable(list.subList(i * MAX, subsize > list.size() ? list.size() : subsize),cyclicBarrier));
        }
        
        cyclicBarrier.await();
        executors.shutdown();
        System.out.println("開始進入第二步操作! ");
        
        
        System.out.println("end! ");
    }
}
使用柵欄CyclicBarrier實現和上面閉鎖CountDownLatch相同的功能。

相關推薦

閉鎖CountDownLatch柵欄CyclicBarrier異同舉例

CountDownLatch和CyclicBarrier的主要聯絡和區別如下: 1.閉鎖CountDownLatch做減計數,而柵欄CyclicBarrier則是加計數。 2.CountDownLatch是一次性的,CyclicBarrier可以重用。 3.CountDow

Java併發程式設計閉鎖CountDownLatch柵欄(CyclicBarrier)

柵欄類似閉鎖,但是它們是有區別的. 1.閉鎖用來等待事件,而柵欄用於等待其他執行緒.什麼意思呢?就是說閉鎖用來等待的事件就是countDown事件,只有該countDown事件執行後所有之前在等待的執行緒才有可能繼續執行;而柵欄沒有類似countDown事件控

Java併發程式設計實戰:閉鎖CountDownLatch柵欄CyclicBarrier與訊號量Semaphore

整體上對三個概念進行一個說明: CountDownLatch和CyclicBarrier都能夠實現執行緒之間的等待,只不過它們側重點不同: CountDownLatch是閉鎖,相當於一扇門:在閉鎖達到結束狀態之前,這扇門一直是關閉的,並且沒有任何執行緒能夠通過,當到達結束

java多執行緒併發系列閉鎖(Latch)柵欄CyclicBarrier

-閉鎖(Latch) 閉鎖(Latch):一種同步方法,可以延遲執行緒的進度直到執行緒到達某個終點狀態。通俗的講就是,一個閉鎖相當於一扇大門,在大門開啟之前所有執行緒都被阻斷,一旦大門開啟所有執行緒都將通過,但是一旦大門開啟,所有執行緒都通過了,那麼這個閉鎖的狀態就失效了,門

並發編程常用工具類countDownLatchcyclicBarrier的使用對比

開放 spa 圖片 我們 啟用 線程 分享 ride 在線 1.CountDownLatch countDownLatch的作用是讓一組線程等待其他線程完成工作以後在執行,相當於加強版的join(不懂可以百度一下join的用法),一般在初始化的時候會在構

多執行緒CountDownLatchCyclicBarrier的區別用法

一.CountDownLatch的使用 CountDownLatch經常用於監聽某些初始化操作,等初始化執行完畢後,再通知主執行緒繼續工作。 CountDownLatch定義: 一個同步輔助類,在完成一組正在其他執行緒中執行的操作之前,它允許一個或多個執行緒一直等待。用給定的計數 初

多執行緒學習筆記六併發工具類CountDownLatchCyclicBarrier

目錄 簡介 CountDownLatch 示例 實現分析 CountDownLatch與Thread.join() CyclicBarrier 實現分析 CountDownLatch和CyclicBarrier區別 簡介

多執行緒CountDownLatchCyclicBarrier的區別 以及舉例

在網上看到很多人對於CountDownLatch和CyclicBarrier的區別簡單理解為CountDownLatch是一次性的,而CyclicBarrier在呼叫reset之後還可以繼續使用。那如果只是這麼簡單的話,我覺得CyclicBarrier簡單命名為Reset

CountDownLatchCyclicBarrier

fin set方法 ren div exce name JD 繼續 override CountDownLatch CountDownLatch是jdk5 java.util.concurrent新增的的工具類 使用場景。導出excel需要解析創建多個sheel。創建

J.U.C工具類中的CountDownLatchCyclicBarrier

內部 inter 同步 結果 異常 輔助 ber 計數 損壞 講解CyclicBarrier       API文檔是這樣介紹的:一個同步輔助類,它允許一組線程互相等待,直到到達某個公共屏障點(common bar

CountDownLatchCyclicBarrier的比較

之間 攔截 countdown 多個 等待 執行 不可 初始 無法 1.CountDownLatch是線程組之間的等待,即一個(或多個)線程等待N個線程完成某件事情之後再執行;而CyclicBarrier則是線程組內的等待,即每個線程相互等待,即N個線程都被攔截之後,然後依

CountDownLatchCyclicBarrier模擬同時並發請求

import 結構 gate 初始化 lee 的區別 pre url 架構師 有時候要測試一下某個功能的並發能力,又不要想借助於其他測試工具,索性就自己寫簡單的demo模擬一個並發請求就最方便了。如果熟悉jemter的測試某接口的並發能力其實更專業,此處只是自己折騰著玩。

多執行緒(十一): 計數器CountDownLatchCyclicBarrier

public static void main(String[] args) { System.out.println(new Date() + "\t" + Thread.currentThread().getName() + "\t\trunning..."); Th

java併發學習03---CountDownLatch CyclicBarrier

CountDownLatch,顧名思義就是一個倒計時器。(其實Latch的意思是門閂,這個詞的本意是不斷的計數減一,減到0了就開啟門閂放行,但通常我們還是叫它倒計時器) 這個倒計時器和我們傳統意義上的倒計時器並不完全一樣,這個倒計時器的意思是,一開始規定幾個執行緒(比如說我們這裡一開始有10個執行緒),那麼

多執行緒CountDownLatch &amp; CyclicBarrier

CountDownLatch 俗稱閉鎖 建構函式中可以傳遞一個count 非負的整數值的數字,表示計數值,當這個計數值減到為0時,才能繼續執行,比如說計算幾個執行緒執行消耗時間 。CyclicBarrier 俗稱同步屏障,它的建構函式有兩種,其他一個也是傳遞一個非負的整數值,表示幾個執行緒

Java併發程式設計(十二)CountDownLatchCyclicBarrier

一、CountDownLatch java.util.concurrent.CountDownLatch可以允許一個或多個執行緒等待其他執行緒操作。從countdown字面意義也可以理解,它是類似於一個倒計時鎖,這個倒計時是原子操作,同一時刻只能有一個執行緒操作倒計時。 CountDownL

Java併發基礎:CountDownLatchCyclicBarrier

CountDownLatch概括 CountDownLatch能夠使一個執行緒在等待其他一個或多個執行緒執行結束之後,再繼續執行。 使用一個計數器進行實現。計數器初始值為執行緒的數量。當每一個執行緒完成自己任務後,計數器的值就會減一。當計數器的值為0時,表示所有的執行緒都

一次刪資料而認識的CountDownLatchCyclicBarrier

公司之前有個任務,要求刪除一張資料庫表裡面2018/2/1之前的資料。這張表裡面存放的是車輛定位資料,一輛車每天能產生4000+條定位資料,所以整個表蠻大的,有65億+條資料。而且還有要求:根據每個地區要統計出來這個地區刪除了多少條資料。其中2月1號之前的有10億多條。當然這

CountDownLatchCyclicBarrier模擬同時併發請求

  有時候要測試一下某個功能的併發能力,又不要想借助於其他測試工具,索性就自己寫簡單的demo模擬一個併發請求就最方便了。如果熟悉jemter的測試某介面的併發能力其實更專業,此處只是自己折騰著玩。 CountDownLatch和CyclicBarrier是jdk concurrent包下非常有用的兩個併發工

同步計數器CountDownLatch CyclicBarrier

CountDownLatch ,把一個工作分給5個人,5個執行緒都執行完了,呼叫countDown,給計數器減數,而主執行緒await,等數為零,主執行緒繼續往下執行,即5條執行緒都完成才算工作完成。 內部很簡單,還是繼承AQS,把設定的數量賦值給state,countDo