引言
JUC即java.util.concurrent,是java提供的用於多線程處理的工具類庫。重點關注 ConcurrentXXX、AtomicXXX、Executor、Caller&&Future、Queue、Locks。
打開jdk包,JUC代碼就在rt.jar包中,concurrent下有atomic和locks兩個package,並且還有concurrentXXX、Executor、Future、Queue等。想查看源碼的話,JDK 安裝的目錄下有個 src.zip —— 這就是源碼。
AtomicXXX,atomic即原子類,如圖:
常用工具類及其作用
1、基本類型的原子類
AtomicBoolean,AtomicInteger,AtomicLong,DoubleAccumulator,DoubleAdder,LongAccumulator,LongAdder 都是基本數據類型的原子類,更適合高並發場景。
以 AtomicLong 和 LongAdder 來說,AtomicLong 是通過 unsafe 類實現的,基於 CAS。unsafe 類是底層工具類,JUC 中很多類的底層都使用到了 unsafe 包中的功能。unsafe 類提供了類似 C 的指針操作,提供 CAS 等功能。並且 unsafe 類中的所有方法都是 native 修飾的。在說 AtomicXXX 之前,已經說過了關於 CAS的相關知識,並發與多線程【四】——同步與互斥。
LongAdder、DoubleAccumulator,DoubleAdder,LongAccumulator 四個類是 JDK1.8 中提供的更高效的操作類。LongAdder 基於 Cell 實現,使用分段鎖思想,是一種空間換時間的策略,更適合高並發的場景。
LongAccumulator 提供了比 LongAdder 更強大的功能,能夠指定對數據的操作規則,例如可以把數據的相加操作改為相乘操作。
2、對對象的原子讀寫功能的類
AtomicReference、AtomicStampedReference、AtomicMarkableReference 類中提供了對對象的原子讀寫功能,后兩個類用於解決前面說過的 ABA 問題,分別基於時間戳和標記位來解決問題。
3、鎖相關的類
鎖相關的類,ReentrantLock、ReentrantReadWriteLock、StampedLock、LockSupport。
ReentrantLock 前面已經說過是重入鎖。與 ReentrantLock 獨占鎖不同的是,Sempaphore 是共享鎖,允許多個線程共享資源,適用於限制使用共享資源線程數量的場景,例如100輛車要使用20個停車位,那么最多允許20個車占用停車位。
StampedLock是 JDK1.8 改進的讀寫鎖,是使用一種 CLH 的樂觀鎖,能夠有效防止寫飢餓。所謂寫飢餓是指在多線程讀寫時,讀線程訪問非常頻繁,導致總是有讀線程占用資源,寫線程很難加上寫鎖。
4、異步執行相關的類
Executors、ForkJoinPool、FutureTask、CompletableFuture是異步執行相關的類。
JDK1.8中提供的 CompletableFuture 可以支持流試調用,可以很方便的進行多 future 的組合使用,例如可以同時執行兩個異步任務,然后對執行結果進行合並處理,還可以很方便的設置完成時間。
JDK1.7中提供的 ForkJoinPool 采用分治思想,將大任務分解成多個小任務處理,然后再合並處理結果。ForkJoinPool 的特點是使用工作竊取算法,可以有效平衡多任務時間長短不一的場景。
5、常用的阻塞隊列
線程池講解的時候已經簡單介紹過阻塞隊列,這里補充一下LinkedBlockingDeque、ArrayBlockingQueue。
LinkedBlockingDeque 是雙端隊列,也就是可以分別從隊頭和隊尾操作入隊、出隊。
ArrayBlockingQueue 是單端隊列,只能從隊尾入隊,隊頭出隊。
6、控制多線程協作時使用的類
CountdownLatch、CyclicBarrier、Semaphore 是控制多線程協作時使用的類。
CountdownLatch 實現計數器功能,可以用來控制等待多個線程執行任務后進行匯總。
CyclicBarrier 可以讓一組線程等待至某個狀態之后,再同時執行,一般在測試時使用,可以讓多線程更好的並發執行。
Semaphore 用來控制對共享資源的訪問並發度。
7、常用的集合類
ConcurrentHashMap、CopyOnWriteArrayList是常用的兩個集合類。
ConcurrentHashMap 可以拉出來一章單獨講。
這里了解一下 CopyOnWriteArrayList,COW 通過寫入數據時進行 copy 修改,然后更新引用的方式,來消除並行讀寫中的鎖使用,比較適合讀多寫少,數據量比較小,但是並發非常高的場景。
擴展
- https://blog.csdn.net/a953713428/article/details/54384166