併發程式設計 基礎篇

2021-10-08 06:07:34 字數 1944 閱讀 3508

當前物件型別

物件頭長度

陣列3字長

非陣列2字長

長度內容

說明1個字長(32bit/64bit)

mark world

儲存物件的hashcode以及鎖的資訊

1個字長

class metedata address

儲存物件型別資料的指標

1個字長

array length

陣列長度(如果物件是陣列)

鎖狀態25bit

4bit

1bit偏向鎖標誌位

2bit鎖標誌位

無鎖hashcode

物件分代年齡001

鎖狀態30bit

2bit鎖標誌位

輕量級鎖

指向執行緒棧中鎖記錄的指標00

鎖狀態30bit

2bit鎖標誌位

重量級鎖

指向互斥量(重量級鎖)的指標10

鎖狀態30bit

2bit鎖標誌位

gc標記空11

鎖狀態23bit

2bit

1bit偏向鎖標誌位

2bit鎖標誌位

偏向鎖線程id

epoch101

加鎖 偏向鎖的撤銷加鎖

釋放鎖經過輕量級鎖變化得到的重量級鎖。轉化為重量級鎖的前提是:多個執行緒存在競爭鎖。

鎖型別優點

缺點適用場景

偏向鎖加鎖解鎖不需要額外消耗,和執行非同步方法差不多

如果存在鎖競爭,會帶來額外鎖撤銷的消耗

只有乙個執行緒訪問同步塊

輕量級鎖

競爭的執行緒不會阻塞,提高了程式的響應速度

得不到鎖競爭的執行緒,自旋消耗cpu

追求響應時間,同步塊執行速度非常快

重量級鎖

執行緒不使用自旋,不消耗cpu

執行緒阻塞,響應時間緩慢

追求吞吐量,同步塊執行速度較長

如果記憶體中的a值和你認為的a值一致,即在當前執行緒對a變數進行修改時,沒有其他執行緒對a進行過修改,當前修改操作成功,返回成功。

if current_a == expected_a:

current_a = altered_a

return true

如果值不一致,即當前執行緒對a變數進行修改時,有其他執行緒對a變數進行修改過,當前修改操作終止,返回失敗。

else

return false

aba問題
兩個執行緒進行同步操作,執行緒1獲取到共享變數v的值為a,然後此時執行緒2對共享變數v進行操作將它改為b,然後又改為了a,此時執行緒1進行cas操作發現v的值還是a,認為這段時間沒有執行緒對v進行操作,然後執行對v的操作。這聽上去沒有什麼問題,然而實際應用中會帶來意想不到的問題。

發生原因

這個問題存在的根本原因是cas只對值進行判斷,會丟失某些執行緒對變數的操作。

場景只要當前賬戶餘額小於100元的,免費發50元。

解決加版本號,對每個變數不僅僅記錄他的值,而且記錄發生時的版本(比如通過新增乙個flag,來標記是否被處理過,或者記錄時間等資訊),將這兩個值作為乙個整體,讓cas進行判斷。

這樣每次比對時不只是比對值,還比對版本號,就不會發生aba問題了。

典型實現

類似的處理還有資料庫中對資料行的操作也可以採用加版本號來解決。

迴圈時間長開銷大

如果迴圈cas操作一直不成功,會給cpu帶來很大開銷。

只能保證乙個共享變數的原子操作

解決將多個共享變數合併成乙個共享變數來操作,

典型實現

讀寫鎖中,將讀狀態和寫狀態放在乙個變數中,低16位表示寫狀態,高16位表示讀狀態。

併發程式設計雜篇

atomically adds the given value to the current value.param delta the value to add return the updated value public final intaddandget int delta public ...

併發程式設計 執行緒篇

public class shutdown private static class runner implements runnable system.out.println count i i public void cancel 本質 對乙個物件的監視器 monitor 進行獲取,而這個獲取過...

併發程式設計基礎

從本質上來說,作業系統其實就是人為編寫的一種軟體,只不過它是一種操作計算機系統的軟體,所有的應用型軟體幾乎都要通過作業系統才能執行來執行功能,沒有不依靠作業系統就能執行功能的應用軟體 除非你真的很厲害,能夠自己操作相應的儲存器 cpu等硬體來提 用軟體的執行條件 一方面,它為應用軟體和使用者提供了操...