併發編程系列:4大併發工具類的功能、原理、以及應用場景

一:併發工具包數據庫

1.併發工具類數組

提供了比synchronized更加高級的各類同步結構:包括CountDownLatch、CyclicBarrier、Semaphore等,能夠實現更加豐富的多線程操做。安全

2.併發容器數據結構

提供各類線程安全的容器:最多見的ConcurrentHashMap、ConcurrentSkipListMap,實現線程安全的動態數組CopyOnWriteArrayList等。多線程

3.併發隊列併發

各類BlockingQueue的實現:經常使用的ArrayBlockingQueue、SynchorousQueue、特定場景的PriorityBlockingQueue。框架

4.Executor框架工具

能夠建立各類不一樣類型的線程池,調度任務運行等,絕大部分狀況下,再也不須要本身從頭實現線程池和任務調度器。學習

2、常見的併發容器ui

1.ConcurrentHashMap

常用的併發容器,JDK 1.7和1.8的底層數據結構發生了變化(後續文章會詳解),這裏能夠建議學習順序以下:從Java7 HashMap -> Java7 ConcurrentHashMap -> Java8 HashMap -> Java8 ConcurrentHashMap,這樣能夠更好的掌握這個併發容器,畢竟都是從HashMap進化而來。

2.ConcurrentSkipListMap

在意順序,須要對數據進行很是頻繁的修改

3.CopyOnWrite容器

CopyOnWrite容器即寫時複製的容器。從JDK1.5開始Java併發包裏提供了兩個使用CopyOnWrite機制實現的併發容器,CopyOnWriteArrayList和CopyOnWriteArraySet。

4.各類併發隊列的實現

如各類BlockedQueue實現,比較典型的ArrayBlockingQueue、SynchorousQueue。

3、常見的併發工具

1.CountDownLatch

功能:

CountDownLatch是一個同步的輔助類,容許一個或多個線程,等待其餘一組線程完成操做,再繼續執行。

原理:

CountDownLatch是經過一個計數器來實現的,計數器的初始值爲須要等待線程的數量。

eg:CountDownLatch c = new CountDownLatch(10); // 等待線程的數量爲10

主線程調用CountDownLatch的await()方法會阻塞當前線程(即:主線程在閉鎖上等待),直到計數器的值爲0。

當一個工做線程完成了本身的任務後,調用CountDownLatch的countDown()方法,計數器的值就會減1。

當計數器值爲0時,說明全部的工做線程都執行完了,此時,在閉鎖上等待的主線程就能夠恢復執行任務。

應用場景:

倒數計時器

例如:一種典型的場景就是火箭發射。在火箭發射前,爲了保證萬無一失,每每還要進行各項設備、儀器的檢查。 只有等全部檢查完畢後,引擎才能點火。這種場景就很是適合使用CountDownLatch。

它可使得點火線程,等待全部檢查線程所有完工後,再執行

使用方式:

static final CountDownLatch end = new CountDownLatch(10);end.countDown(); end.await(); 2.CyclicBarrier

功能:

CyclicBarrier的字面意思是可循環使用(Cyclic)的屏障(Barrier)。它要作的事情是,讓一組線程到達一個屏障(也能夠叫同步點)時被阻塞,直到最後一個線程到達屏障時,屏障纔會開門,全部被屏障攔截的線程纔會繼續運行。

和CountDownLatch類似,也是等待某些線程都作完之後再執行。

與CountDownLatch區別:

在於這個計數器能夠反覆使用。好比,假設咱們將計數器設置爲10。那麼湊齊第一批1 0個線程後,計數器就會歸零,而後接着湊齊下一批10個線程。

原理:

1)CyclicBarrier是經過一個計數器來實現的,計數器的初始值爲須要等待線程的數量。eg:CyclicBarrier c = new CyclicBarrier(2); // 等待線程的數量爲2

2)每一個線程調用CyclicBarrier的await()方法,使本身進入等待狀態。

3)當全部的線程都調用了CyclicBarrier的await()方法後,全部的線程中止等待,繼續運行。

使用方式:

public CyclicBarrier(int parties, Runnable barrierAction) barrierAction就是當計數器一次計數完成後,系統會執行的動做await()

3.信號量Semaphore

功能:

Java提供了經典信號量Semaphore的實現,它經過控制必定數量的許可(permit)的方式,來達到限制通用資源訪問的目的。例如:控制併發的線程數。

原理:

1)Semaphore是經過一個計數器(記錄許可證的數量)來實現的,計數器的初始值爲須要等待線程的數量。

eg:Semaphore s = new Semaphore(10); // 線程最大的併發數爲10

2)線程經過acquire()方法獲取許可證(計數器的值減1),只有獲取到許可證才能夠繼續執行下去,不然阻塞當前線程。

3)線程經過release()方法歸還許可證(計數器的值加1)。

說明:使用tryAcquire()方法能夠當即獲得執行的結果:嘗試獲取一個許可證,若獲取成功,則當即返回true,若獲取失敗,則當即返回false。

應用場景:

Semaphore能夠用於作流量控制,特別是公用資源有限的應用場景,好比數據庫鏈接。

舉一個場景:例如在車站、機場等出租車時,當不少空出租車就位時,爲防止過分擁擠,調度員指揮排隊等待坐車的隊伍一次進來5我的上車,等這5我的坐車出發,再放進去下一批。這和Semaphore的工做原理有些相似。

4.交換者Exchanger

功能:

Exchanger(交換者)是一個用於線程間協做的工具類。Exchanger用於進行線程間的數據交換。

原理:

它提供一個同步點,在這個同步點兩個線程能夠交換彼此的數據。

這兩個線程經過exchange方法交換數據, 若是第一個線程先執行exchange方法,它會一直等待第二個線程也執行exchange,當兩個線程都到達同步點時,這兩個線程就能夠交換數據,將本線程生產出來的數據傳遞給對方。

Exchanger的應用場景

Exchanger能夠用於校對工做的場景。

相關文章
相關標籤/搜索