標籤:java 並發 編程
Java 並發包
並發包中除了提供高效能的安全執行緒的集合對象外,還提供了很多並發情境需要的原子操作類,例如AtomicInteger,另外還提供了一些用於避免並發時資源衝突的Lock及Condition類。
ConcurrentHashMap
安全執行緒的HashMap的實現。
維護的是一個Segment對象數組,segment繼承ReentrantLock
| 方法 |
意義 |
| ConcurrentHashMap() |
|
| put(Object key,Object value) |
ConcurrentHashMap基於concurrencyLevel劃分出了多個segment來對key-velue進行儲存,從而避免每次put操作都得鎖住整個數組。在預設的情況下,最佳情況可以允許16個線程並發無阻塞的操作集合對象 |
| remove(Object key) |
|
| get(Object) |
|
| containsKey(Object key) |
|
| keySet().iterator() |
|
CopyOnWriteArrayList
CopyOnWriteArrayList是一個安全執行緒,並且在讀操作時無鎖的ArrayList
在讀多寫少,且線程數很多的情況下,比較合適
CopyOnWriteArraySet
基於CopyOnWriteArrayList實現,唯一的不同是在add時調用的是CopyOnWriteArrayList的addIfAbsent方法
CopyOnWriteArraySet在add時每次都要進行數組遍曆,因此效能會略低於CopyOnWriteArrayList.
ArrayBlockingQueue
一個由數組支援的有界阻塞隊列。此隊列按 FIFO(先進先出)原則對元素進行排序。隊列的頭部 是在隊列中存在時間最長的元素。隊列的尾部 是在隊列中存在時間最短的元素。新元素插入到隊列的尾部,隊列擷取操作則是從隊列頭部開始獲得元素。
這是一個典型的“有界緩衝區”,固定大小的數組在其中保持生產者插入的元素和使用者提取的元素。一旦建立了這樣的緩衝區,就不能再增加其容量。試圖向已滿隊列中放入元素會導致操作受阻塞;試圖從空隊列中提取元素將導致類似阻塞。
- ArrayBlockingQueue(int )
- offer(E,long,TimeUnit)
將指定的元素插入此隊列的尾部,如果該隊列已滿,則在到達指定的等待時間之前等待可用的空間。
- poll(long,TimeUnit)
擷取並移除此隊列的頭部,在指定的等待時間前等待可用的元素(如果有必要)。
- put(E)
將指定的元素插入此隊列的尾部,如果該隊列已滿,則等待可用的空間。
- take()
擷取並移除此隊列的頭部,在元素變得可用之前一直等待(如果有必要)。
AtomicInteger
支援原子操作的Integer類,
- AtomicInteger()
建立具有初始值 0 的新 AtomicInteger。
- AtomicInteger(int initialValue)
建立具有給定初始值的新 AtomicInteger。
- int addAndGet(int delta)
以原子方式將給定值與當前值相加。
- int decrementAndGet()
以原子方式將當前值減 1。
- int incrementAndGet()
以原子方式將當前值加 1。
- get()
擷取當前值。
- set(int newValue)
設定為給定值。
Executors
建立線程池
- newFixedThreadPool(int)
- newCachedThreadPool()
- newSingleThreadPool()
FutureTask
可用於非同步擷取執行結果或取消執行任務的情境,通過傳入Runnable或Callable的任務給FutureTask,直接調用其run方法或放入線程池執行,之後可在外部通過FutureTask的get非同步擷取執行結果。FutureTask可以確保即使調用了多次run方法,它都會執行一次Runnable或Callable任務,或者通過cancle取消FutureTask的執行。
| 方法 |
意義 |
| FutureTask(Callable callable) |
建立一個 FutureTask,一旦運行就執行給定的 Callable。 |
| FutureTask(Runnable runnable, V result) |
建立一個 FutureTask,一旦運行就執行給定的 Runnable,並安排成功完成時 get 返回給定的結果 。 |
| boolean cancel(boolean mayInterruptIfRunning) |
試圖取消對此任務的執行。 |
| protected void done() |
當此任務轉換到狀態 isDone(不管是正常地還是通過取消)時,調用受保護的方法。 |
| V get() |
如有必要,等待計算完成,然後擷取其結果。 |
| V get(long timeout, TimeUnit unit) |
如有必要,最多等待為使計算完成所給定的時間之後,擷取其結果(如果結果可用)。 |
| boolean isCancelled() |
如果在任務正常完成前將其取消,則返回 true。 |
| boolean isDone() |
如果任務已完成,則返回 true。 |
| void run() |
除非已將此 Future 取消,否則將其設定為其計算的結果。 |
| protected boolean runAndReset() |
執行計算而不設定其結果,然後將此 Future 重設為初始狀態,如果計算遇到異常或已取消,則該操作失敗。 |
| protected void set(V v) |
除非已經設定了此 Future 或已將其取消,否則將其結果設定為給定的值。 |
Semaphore
一個計數訊號量。從概念上講,訊號量維護了一個許可集。如有必要,在許可可用前會阻塞每一個 acquire(),然後再擷取該許可。每個 release() 添加一個許可,從而可能釋放一個正在阻塞的擷取者。
| 方法 |
意義 |
| Semaphore(int permits) |
建立具有給定的許可數和非公平的公平設定的 Semaphore。 |
| Semaphore(int permits, boolean fair) |
建立具有給定的許可數和給定的公平設定的 Semaphore。 |
| void acquire() |
從此訊號量擷取一個許可,在提供一個許可前一直將線程阻塞,否則線程被中斷。 |
| void release() |
釋放一個許可,將其返回給訊號量。 |
| public boolean tryAcquire() |
僅在調用時此訊號量存在一個可用許可,才從訊號量擷取許可。(立即擷取許可) |
CountDownLatch
用給定的計數 初始化 CountDownLatch。由於調用了 countDown() 方法,所以在當前計數到達零之前,await 方法會一直受阻塞。之後,會釋放所有等待的線程,await 的所有後續調用都將立即返回。這種現象只出現一次——計數無法被重設。
| 方法 |
意義 |
| void await() |
使當前線程在鎖存器倒計數至零之前一直等待,除非線程被中斷。 |
| boolean await(long timeout, TimeUnit unit) |
使當前線程在鎖存器倒計數至零之前一直等待,除非線程被中斷或超出了指定的等待時間。 |
| void countDown() |
遞減鎖存器的計數,如果計數到達零,則釋放所有等待的線程。 |
| long getCount() |
返回當前計數。 |
| String toString() |
返回標識此鎖存器及其狀態的字串。 |
CyclicBarrier
CyclicBarrier和CountDownLatch不同,CyclicBarrier是當await的數量到達了設定的數量後,才繼續往下執行
該 barrier 在釋放等待線程後可以重用,所以稱它為迴圈 的 barrier。
| 方法 |
意義 |
| CyclicBarrier(int parties) |
建立一個新的 CyclicBarrier,它將在給定數量的參與者(線程)處於等待狀態時啟動,但它不會在啟動 barrier 時執行預定義的操作。 |
| int await() |
在所有參與者都已經在此 barrier 上調用 await 方法之前,將一直等待。 |
ReentrantLock
一個可重新進入的互斥鎖 Lock,它具有與使用 synchronized 方法和語句所訪問的隱式監視器鎖相同的一些基本行為和語義,但功能更強大。
| 方法 |
意義 |
| ReentrantLock() |
建立一個 ReentrantLock 的執行個體。 |
| void lock() |
擷取鎖。 |
| void unlock() |
試圖釋放此鎖。 |
| Condition newCondition() |
返回用來與此 Lock 執行個體一起使用的 Condition 執行個體。 |
Condition
條件(也稱為條件隊列 或條件變數)為線程提供了一個含義,以便在某個狀態條件現在可能為 true 的另一個線程通知它之前,一直掛起該線程(即讓其“等待”)。
Condition 執行個體實質上被綁定到一個鎖上。要為特定 Lock 執行個體獲得 Condition 執行個體,請使用其 newCondition() 方法。
- void await()
當前線程在接到訊號或被中斷之前一直處於等待狀態。
- void signal()
喚醒一個等待線程。
- void signalAll()
喚醒所有等待線程。
ReentrantReadWriteLock
讀寫鎖,此鎖最多支援 65535 個遞迴寫入鎖和 65535 個讀取鎖。試圖超出這些限制將導致鎖方法拋出 Error。
可以方便實現讀者–寫者問題
| 方法 |
意義 |
| ReentrantReadWriteLock.ReadLock readLock() |
返回用於讀取操作的鎖。 |
| ReentrantReadWriteLock.WriteLock writeLock() |
返回用於寫入操作的鎖。 |
ReentrantReadWriteLock.ReadLock
ReentrantReadWriteLock.WriteLock
Exchager
可以在對中對元素進行配對和交換的線程的同步點。每個線程將條目上的某個方法呈現給 exchange 方法,與夥伴線程進行匹配,並且在返回時接收其夥伴的對象。Exchanger 可能被視為 SynchronousQueue 的雙向形式。Exchanger 可能在應用程式(比如遺傳演算法和管道設計)中很有用。
Exchanger<V>
V - 可以交換的物件類型
| 方法 |
意義 |
| Exchanger() |
建立一個新的 Exchanger。 |
| V exchange(V x) |
等待另一個線程到達此交換點(除非當前線程被中斷),然後將給定的對象傳送給該線程,並接收該線程的對象。 |
| V exchange(V x, long timeout, TimeUnit unit) |
等待另一個線程到達此交換點(除非當前線程被中斷,或者超出了指定的等待時間),然後將給定的對象傳送給該線程,同時接收該線程的對象。 |
總結
並發架構下的集合類:
- ArrayBlockingQueue:一個有界阻塞隊列,可以實現生產者–消費者問題
- CopyOnWriteArrayList:ArrayList 的一個安全執行緒的變體,其中所有可變操作(add、set 等等)都是通過對底層數組進行一次新的複製來實現的。
- CopyOnWriteArraySet:最適合於具有以下特徵的應用程式:set 大小通常保持很小,唯讀操作遠多於可變操作,需要在遍曆期間防止線程間的衝突。
- LinkedBlockingQueue:連結隊列的輸送量通常要高於基於數組的隊列,但是在大多數並發應用程式中,其可預知的效能要低。
- ConcurrentLinkedQueue:基於連結節點的無界安全執行緒隊列
- ConcurrentHashMap:安全執行緒的HashMap實現
工具類
- CountDownLatch
- CyclicBarrier
cyclic:迴圈的,周期的
上述兩個工具類都可以用來實現一個線程等待多個線程結束,從而確保幾乎所有線程同時執行
原子操作
- AtomicInteger
- AtomicBoolean
- …
擷取其他線程的傳回值
資源競爭
互斥
- ReentrantLock
- Condition
- ReentrantReadWriteLock
- ReentrantReadWriteLock.WriteLock
- ReentrantReadWriteLock.ReadLock
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
Java並發包總結