synchronized加鎖過程

2021-10-04 01:38:01 字數 2529 閱讀 2875

保證執行緒同步的方法(執行緒通訊的方法),wait/notify ,synchronized,reentranklock,,

我所認為的認為的synchronized,鎖的膨脹過程,這是乙個怎樣的概念:無鎖狀態》偏向鎖》輕量級鎖》重量級鎖;

首先來說說為什麼是這樣設定(我所認為的),首先來說說物件頭吧,其實我只知道冰山一角,我匯入乙個jar包,jol-core-0.8.jar,這個jar包可以去檢視我們的物件頭,今天以64位計算機來說,我們先建立乙個最簡單的物件,

public

class

l

對,沒錯,什麼東西都沒有,來看看建立乙個l的物件的物件頭是什麼樣子

l l=

newl()

;// l.hashcode();

// system.out.println(classlayout.parseclass(l.class).toprintable());

system.out.

println

(classlayout.

parseinstance

(l.class).

toprintable()

);

offset  size                                              type description                               value

04(object header)

0100

0000

(00000001

00000000

00000000

00000000)(

1)44

(object header)

0000

0000

(00000000

00000000

00000000

00000000)(

0)84

(object header) df 03

0020

(11011111

00000011

00000000

00100000)(

536871903

)

這裡只是擷取了物件頭,採用小端,可以看出,在64為作業系統,乙個物件物件頭為96bit,(物件頭由倆個詞組成,mark word,klass pointer(類的元資料位址,方法區的類的模板資訊))

其中mark word為64bit,klass pointer為32bit

都知道乙個物件由物件頭+例項資料+填充資料,構成,物件頭主要有乙個物件的鎖狀態,hash值,分代年齡等構成

乙個物件鎖狀態,也是在物件頭中有2個bit所儲存(還有gc標記也有一位),一共是三位所儲存;

在jdk1.6之前synchronized是一把重量級鎖,(它只要有執行緒競爭就會有cup的使用者態和核心態之間的轉變),所以才出現了乙個reentranklock的鎖,而這個鎖效能在jdk1.6之前是要比sychronized的效能好很多的,reentranklock詳解在後續文章中;在jdk1.6之後,oracle吧,將synchronized優化,也就是我們所說的鎖的膨脹過程;我們乙個狀態乙個狀態的說:

偏向鎖:適用於執行緒少或者執行緒不競爭(交替執行,乙個完了,下乙個才來),當乙個執行緒經過同步**塊或同步方法時,會去加鎖(假設目前無鎖狀態),那麼如何加呢?首先沒有被加鎖時,這個物件或者類物件的物件頭標記為無鎖狀態,當第乙個執行緒,執行緒1來時,可以直接加鎖,那麼這個物件的物件頭就變為偏向鎖狀態;即這個執行緒的執行緒id會被記錄在被鎖住物件的物件頭中,這就是乙個偏向執行緒1的偏向鎖,即使這個執行緒執行完,退出了同步方法,仍然不會去釋放鎖(所以鎖的膨脹過程時不可逆的),這個鎖仍然是偏向這個執行緒的偏向鎖,而這個執行緒下次在進入這個同步方法時,只需要判斷當前物件的物件頭的執行緒id與當前執行緒的執行緒id相同否,相同則直接進入,不同則判斷物件頭中儲存的執行緒id對應的執行緒是否執行完畢(是否已經退出同步),如果執行完畢,則將物件頭中的執行緒id改為當前執行緒的執行緒id,當前執行緒進入(

同樣,執行完後也不會釋放鎖),如果上乙個執行緒還沒有執行完,則此時就是競爭的狀態而非交替了,鎖膨脹為輕量級鎖;

那麼為什麼引入偏向鎖呢?

同乙個執行緒只需加鎖一次,可以重複進出,不需要花費大量時間去加鎖,解鎖,同時這個被加鎖的執行緒「被偏向了」,即這個執行緒進出快

重量級鎖:就是jdk1.6之前的鎖,讓所有等待的執行緒全部去阻塞,也就是讓他們由作業系統做執行緒上下文的切換,由使用者態轉變為核心態,效能很低,但為了保證同步,只有這樣,因為當很多執行緒競爭時,大量執行緒自旋會耗費大量cpu,所以讓其阻塞吧

synchronized是一把非公平鎖,即所有等待全部去競爭鎖,沒有先後之分,上述所說執行緒加鎖,物件加鎖,其實是乙個概念,我們都知道一句話:被鎖住的是物件,所以我們針對的是同乙個物件的不同執行緒來加鎖(如果是不同物件,就沒有同步可言了);

以上所述,為筆者學習筆記,僅作參考

synchronized 加鎖保證執行緒安全

synchronized關鍵字最主要有以下3種應用方式 1 例項方法加鎖 非靜態方法 使用synchronized修飾,以便保證執行緒安全 加了synchronized 後同時只能有乙個執行緒訪問該方法。但如果多個例項物件操作,非靜態方法不能保證執行緒安全。public class accounti...

synchronized的幾種加鎖方式

public class synchronizedtest catch interruptedexception e public static void main string args start new thread start 此處列舉的是不同例項呼叫的情況 此處列舉的是同一例項呼叫的情況 ...

synchronized的幾種加鎖方式

public class synchronizedtest catch interruptedexception e public static void main string args start new thread start 此處列舉的是不同例項呼叫的情況 此處列舉的是同一例項呼叫的情況 ...