多執行續處理
- 參考網址
- 多執行續演變
- <= JDK 1.4
- = JDK 1.5
- Thread Pool
- AIO
- Excutor
- Concurrent包
- 創建執行續的4種方式
- Thread
- Runnable
- Callable
- 可以有返回值 , 由FutureTask支持接收結果 , get()->阻塞
- ThreadPool
- 如果沒有執行shutdown() , 執行續會持續進行
- 多執行續的 可見性、原子性、有序性問題
- 可見性 : 基於Java內存模型 , 每一個線程皆會從主存存取共用變數值至工作內存中進行運算 , 導致A線程已修改數據,B線程仍使用舊資料進行運算 , 因此有 Volatile修飾字的解決辦法
- 原子性 : 多個線程存取同一共用變數 , 同時進行"修改"所導致的問題 (Concurrent包)
- 有序性 : JVM因考量效能 , 在解析代碼會將沒有順序關係的變數進行順序調度 , 導致非預期結果
- Volatile 參考
- 保證共享(主)內存刷新
- 符合有序性、可見性
- 不符合原子性
- Concurrent包
- 用於處理多執行續的
- 1.8之後符合CAS(Compare&Swap)演算法(原子性) , 使用native method硬體對併發的支持
- CAS原理
- 內存值V
- 預估值A
- 更新值B
- If V==A , V=B
- 屬於一種樂觀鎖機制
- 含原子操作用的Atomic api
- 常見之Class , 介於Collection之非執行續安全類別~執行續安全類別之間
- ConcurrentHashMap
- ConcurrentSkipListMap
- ConcurrentSkipListSet
- CopyOnWriteArrayList
- CopyOnWriteArraySet
- 常見多執行續"鎖"之種類介紹
- 悲觀鎖
- 當對象被線程鎖上時,其餘線程必須等待鎖釋放才可存取
- 例如 synchronize
- 缺點沒控制好性能通常較差
- 樂觀鎖
- 當未完成操作時 , 進行重試
- 例如 CAS進行硬件級別鎖
- 缺點ABA問題 , 循環開銷大 , 一次只能保證一個共享變數(建議使用synchronize)
- 閉鎖操作
- CountDownLatch用於等待多線程操作完成
- 當計數器=0時代表開鎖
- 同步鎖
- synchronize區塊(隱式鎖)
- synchronize方法(隱式鎖)
- Lock(顯示鎖、樂觀鎖)
- 使用lock() 、 unlock()定義同步區塊
- 搭配condition生成await()、signal()、signalAll()
- Object原生的wait()如同await()建議放在while回圈內,防止虛假喚醒
- 補充
- synchronize屬於對象鎖 , 影響單一對象 , 如果另外生成對象則不影響
- static synchronize屬於類別鎖 , 影響全部對象
- synchronize與static synchronize兩者為獨立運行 , 各別控制運行
- 讀寫鎖
- 寫寫/讀寫兩種線程必須互斥 , 讀寫分離
- 一個 readLock() , 一個 WriteLock()
- Fork/Join框架
沒有留言:
張貼留言