高並發學習(一)
阿新 • • 發佈:2018-09-24
通過 利用 變量 寫在前面 strong ref add 以及 線程中斷
要理解java內存模型以及一些處理高並發的技術手段,理解一些主要的硬件知識是必須的。
一個主要CPU運行計算的步驟例如以下:
- 程序以及數據被載入到主內存
- 指令和數據被載入到CPU的快速緩存
- CPU運行指令,把結果寫到快速緩存
- 快速緩存中的數據寫會主內存
- 高並發的問題:
CPU多級緩存:緩存一致性,亂序執行優化
緩存一致性:eg.(i初值為1,兩個線程對i進行加1操作)兩個線程分別讀取i的值存入各自所在的CPU的高速緩存當中,然後線程1進行加1操作,然後把i的最新值1寫入到內存。此時線程2的高速緩存當中i的值還是0,進行加1操作之後,i的值為1,然後線程2把i的值寫入內存。這樣最終的到的結果就是1,而不是2。
解決方法:
- 通過在總線上加LOCK鎖的方式
- 通過緩存一致性協議 核心思想:當CPU向內存讀入數據時,如果發現操作的變量是共享變量,即在其他CPU中也存在該變量的副本,會發出信號通知其他CPU將該變量的緩存行置為無效狀態,因此當其他CPU需要讀取這個變量時,發現自己緩存中緩存該變量的緩存行是無效的,那麽就會從內存重新讀取。
java內存模型:JMM規定,抽象結構,同步等八種操作及規則
java並發的優勢和風險
優勢:
- 系統可以處理多個請求,相應快
- 磁盤和CPU利用率提升
缺點:
- 線程過多,會消耗內存
- 線程安全性:
原子性:(Atomic 包、cas、syncronized、lock)
- AtomicXXX:核心是Unsafe.compareAndSwapInt(CAS),將主存的值和預期值進行比較,如果相同才進行更新。
- AtomicLong、LongAdder
- AtomicReference、AtomicReferenceFieldUpdater
- AtomicStampReference
- 鎖:
synchronized同步鎖:修飾4種對象(不能繼承):不可中斷鎖,適合競爭不激烈,可讀性好
JMM關於synchronized的兩條規定:
線程解鎖前,必須把共享變量的最新值刷新到主內存
線程加鎖時,將清空工作內存中共享變量的值,從而使用共享變量時需要從主內存中重新讀取最新的值。
修飾區域:
- 修飾代碼塊
- 修飾方法
- 修飾靜態方法
- 修飾類
lock:可中斷鎖,多樣化同步,競爭激烈時能維持常態
- 可見性(syncronized、volitale)
導致共享變量在線程間不可見的原因是:1.線程交叉執行2.重排序結合線程交叉執行3.共享變量更新後的值沒有在工作內存與主存間及時更新
synchronized
volitale關鍵字(作為狀態標記量)特點:1.可見性2禁止指令重排序(加入內存屏障)
- 對volatile變量寫操作時,會在讀操作後加入一條Store屏障指令,將本地內存中的共享變量刷新到主內存
- 對volatile變量讀操作時,會在讀操作前加入一條load屏障指令,從主內存中讀取共享變量
- 有序性(happens-before 原則)
- 程序次序規則(一個線程內:按照代碼順序,書寫在前面的操作先行發生於書寫在後面的操作)
- 鎖定規則
- volatile變量規則
- 傳遞規則
- 線程啟動規則
- 線程中斷規則
- 線程終結規則
- 對象終結規則
高並發學習(一)