
Java并發(fā)編程
并發(fā)編程的優(yōu)勢
提升CPU資源利用率
- CPU緩存
- 操作系統(tǒng)分時復(fù)用
- 指令流水線優(yōu)化
提升吞吐量
提升程序響應(yīng)速度
更好的編程模型
并發(fā)帶來的問題
安全性問題
-
定義:多線程讀寫共享變量時出現(xiàn)不正確的行為
-
原因
-
原子性問題
- CPU時鐘中斷帶來的線程切換
-
可見性問題
- 多核CPU高速緩存之間不可見
-
重排序問題
-
CPU和編譯器會進(jìn)行重排序指令
- 典型問題:單例模式DCL
-
-
-
解決方案
-
解決可見性問題和重排序
-
Java內(nèi)存模型(JMM)
-
按需禁用緩存和編譯優(yōu)化(重排序)
- volatile
- final
Happens-Before規(guī)則
-
-
-
解決原子性問題
-
通用互斥鎖管程模型
-
管程
管理并發(fā)過程中的共享變量及其操作過程
-
MESA模型
線程阻塞隊列
條件變量
條件變量等待隊列
-
編程范式
-
while循壞檢測
- 虛假喚醒
- 條件變更
-
-
sychronized
對象頭鎖結(jié)構(gòu)
monitorenter和monitorexit
-
鎖升級
- 偏向鎖
- 輕量級鎖
- 重量級鎖
-
-
volatile變量讀寫+cas無鎖算法
LOCK指令總線鎖
MESI緩存一致性協(xié)議
unsafe工具類
-
CAS三大注意事項
- ABA問題
- 循壞開銷大
- 多變量問題
-
-
并發(fā)同步工具和機(jī)制
基于AQS的同步組件
-
原子變量
- AtomicLong
- LongAdder
-
等待通知機(jī)制
- wait
- notify/notifyAll
-
線程封閉
- ThreadLocal
非阻塞同步機(jī)制
-
-
活躍性問題
-
死鎖
-
定義
- 一組相互競爭資源的線程因互相等待,導(dǎo)致”永久“阻塞的現(xiàn)象
-
死鎖的四大條件
-
互斥
- 共享資源只能被一個線程占用
-
占有且等待
- 已占有資源的線程,在等待其他資源時不釋放原有資源
-
不可搶占
- 線程不能搶占其他線程已占有的資源
-
循環(huán)等待
- 出現(xiàn)線程之間相互等待對方資源的情況
-
-
打破死鎖
-
打破“占有且等待”
- 一次性申請所有資源
-
打破“不可搶占”
-
已占有資源的線程,如果申請不到其他資源,主動釋放原有資源
- 并發(fā)包的LOCK
-
-
打破“循環(huán)等待”
- 按統(tǒng)一順序申請資源
-
-
-
活鎖
-
沒有阻塞但不滿足條件無法繼續(xù)執(zhí)行
- 等待隨機(jī)時間
-
-
饑餓
-
長期獲取不到資源無法繼續(xù)執(zhí)行
- 公平分配
-
性能問題
-
Amdahl定律
-
使用無鎖算法和數(shù)據(jù)結(jié)構(gòu)
- ThreadLocal
- 寫時復(fù)制
- 樂觀鎖
-
減小鎖持有范圍
-
細(xì)粒度鎖
- 分段鎖
- 讀寫鎖
-
-
-
上下文切換
- 合理配置并發(fā)線程數(shù)
-
偽共享
-
原因
- 最小單位緩存行
-
解決方案
- 變量填充
-
-
衡量指標(biāo)
- 吞吐量
- 延遲時間
- 并發(fā)量
線程生命周期
通用狀態(tài)
-
初始狀態(tài)
- 編程語言特有,操作系統(tǒng)層還沒有真正創(chuàng)建
-
運(yùn)行狀態(tài)
- 運(yùn)行中
-
可運(yùn)行狀態(tài)
- 可分配CPU執(zhí)行
休眠狀態(tài)
終止?fàn)顟B(tài)
Java線程狀態(tài)
NEW(初始化)
RUNNABLE(可運(yùn)行狀態(tài)/運(yùn)行狀態(tài))
-
BLOCKED(阻塞狀態(tài))
- synchronized
WAITING(無限時等待)
-
TIMED_WAITING(有限時等待)
- sleep
- wait()帶超時參數(shù)
- join()帶超時參數(shù)
- LockSupport.park()帶超時參數(shù)
TERMINATED
并發(fā)工具類
Lock
-
和synchronized的區(qū)別
- 響應(yīng)中斷
- 支持超時
- 非阻塞式獲取鎖
Condition
Semaphore
ReadWriteLock和StampedLock
-
ReadWriteLock
- 讀鎖
- 寫鎖
- 鎖不能升級,只能降級。升級會使寫鎖永久阻塞等待
- 寫鎖支持條件變量,讀鎖是不支持條件變量的
-
StampedLock
- 寫鎖
- 悲觀讀鎖
- 樂觀讀
- 加鎖成功會返回stamp,解鎖需要傳入stamp
- 性能更好
- 不可重入
- 不支持條件變量
- 使用readLock() 或writeLock() 時,不能使用阻塞線程的interrupt(),需要使用可中斷的悲觀讀鎖 readLockInterruptibly() 和寫鎖 writeLockInterruptibly()
CountDownLatch
- 解決一個線程等待多個線程的場景
- 計數(shù)器是不能循環(huán)利用
CyclicBarrier
- 一組線程之間互相等待
- 計數(shù)器是可以循環(huán)利用,自動重置
- 可以設(shè)置回調(diào)函數(shù)
并發(fā)容器類
-
List
- CopyOnWriteArrayList
-
Map
- ConcurrentHashMap
- ConcurrentSkipListMap
-
Set
- CopyOnWriteArraySet
- ConcurrentSkipListSet
-
Queue
-
.單端阻塞隊列
- ArrayBlockingQueue
- LinkedBlockingQueue
- SynchronousQueue
- LinkedTransferQueue
- PriorityBlockingQueue
- DelayQueue
-
雙端阻塞隊列
- LinkedBlockingDeque
-
單端非阻塞隊列
- ConcurrentLinkedQueue
-
雙端非阻塞隊列
- ConcurrentLinkedDeque
-
原子類
-
基本數(shù)據(jù)類型
- AtomicBoolean
- AtomicInteger
- AtomicLong
-
對象引用類型
- AtomicReference
- AtomicStampedReference
- AtomicMarkableReference
-
數(shù)組類型
- AtomicIntegerArray
- AtomicLongArray
- AtomicReferenceArray
-
對象屬性更新器
- AtomicIntegerFieldUpdater
- AtomicLongFieldUpdater
- AtomicReferenceFieldUpdater
-
累加器
- DoubleAccumulator
- DoubleAdder
- LongAccumulator
- LongAdder
線程池
- ThreadPoolExecutor
- Executors
- Future
- FutureTask
- CompletableFuture
- CompletionService
- Fork/Join
并發(fā)設(shè)計模式
Immutability模式
- 基礎(chǔ)類型包裝類
Copy-on-Write模式
- 基礎(chǔ)類型包裝類
線程本地存儲模式
- ThreadLocal
Guarded Suspension模式
- 等待喚醒機(jī)制
Balking模式
Thread-Per-Message模式
- 協(xié)程
- Fiber
Worker Thread模式
- Java線程池
兩階段終止模式
生產(chǎn)者-消費(fèi)者模式
- Java線程池
- MQ
參考文檔
JSR 133
XMind - Trial Version