線程-相關(guān)知識點(diǎn)

業(yè)精于勤而荒于嬉,行成于思而毀于隨。

java內(nèi)存模型

java內(nèi)存模型(java memory model)是一種規(guī)范,是解決多線程在用共享內(nèi)存時,因為3級緩存,編譯器重排,cpu亂序執(zhí)行,導(dǎo)致的線程安全問題。
3種問題:原子性,可見性,有序性

關(guān)鍵字volatile

保證可見性,有序性
在實現(xiàn)雙重檢測單例時,就是因為利用了有序性,保證創(chuàng)建對象時按照分配內(nèi)存->內(nèi)存中創(chuàng)建對象-> 變量指向內(nèi)存的執(zhí)行順序。
不能保證原子性,導(dǎo)致一些依賴原值的修改操作,在多線程中會出現(xiàn)問題。
可以用AtomicInteger->longAdder(分段cas并發(fā)時性能好)來實現(xiàn)線程安全。(基于CAS)
寫操作前插入寫寫、寫操作后添加寫讀、讀操作前添加讀讀、讀操作后添加讀寫內(nèi)存屏障,保證可見性和有序性。

實現(xiàn)線程安全思路
  • 鎖(s鎖,AQS鎖
  • cas(AtomicInteger
  • 一個線程一套(ThreadLocal
S鎖

jdk1.5實現(xiàn),是個笨鎖,操作有用戶態(tài)內(nèi)核的上下文切換。
jdk1.6升級了,根據(jù)競爭程度一級一級升級。這里也涉及到了自旋鎖,因為自旋鎖在競爭比較激烈比較費(fèi)cpu,所以最后轉(zhuǎn)為笨鎖,一了百了。


image.png
CAS算法

內(nèi)存值,舊值,新值
線程舊值新值運(yùn)算完之后,回寫內(nèi)存值時,對比內(nèi)存值舊值是否相等。
ABA問題可以加版本號處理。
爭搶比較多比較費(fèi)cpu,但是比起s鎖沒有上下文切換開銷。

AQS抽象同步隊列

state為0說明沒有正在運(yùn)行的線程,可以直接運(yùn)行,運(yùn)行會把state改為1,這時候如果還是這個線程重入加鎖,會再進(jìn)行累加。
雙向鏈表(CHL),有正在運(yùn)行的線程,又不是自己,r鎖默認(rèn)是非公平鎖,會先加到尾插到鏈表里。
r鎖默認(rèn)是非公平鎖,可以創(chuàng)建的時候指定,非公平鎖時新加鎖的線程會先cas2次去爭搶鎖,搶到就繼續(xù)執(zhí)行,否則park放到鏈表尾部。公平鎖模式,會直接放到park鏈表尾部。非公平鎖具有更高的吞度量,因為新加入線程可能直接執(zhí)行,沒有暫停,放入隊列,再喚醒的開銷。

Locksupport.park

  • 響應(yīng)中斷,但不拋出異常。
  • 底層permit布爾值,控制掛起執(zhí)行。

封裝的一些類:

  1. ReentrantLock
    比起s鎖,公平鎖,可中斷,有狀態(tài)。
    代碼塊,需要手動釋放。
    lock.Condition實現(xiàn)了s鎖的wait nofity機(jī)制。
    對應(yīng)await,signal方法。
  2. ReentrantReadWriteLock 讀寫鎖。
  3. Semaphore 信號量,控制線程的數(shù)量。
    acquire()數(shù)量加一,滿了阻塞。
    release()數(shù)量減一。
  4. CountDownLatch 倒計時 實現(xiàn)線程同時運(yùn)行。
    await()阻塞,等待數(shù)減到0。
    countdown()數(shù)量減一。
  5. CyclicBarrier 循環(huán)屏障(比起countdownLatch可以復(fù)用reset)
    await()阻塞,當(dāng)所有數(shù)量線程都走到此步,繼續(xù)執(zhí)行。
ThreadLocal

http://www.itdecent.cn/p/a20af7b7d113

image.png

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容