synchronized和lock全面詳細講解

synchronized和lock應該是最常用的鎖,今天講這2個原理和比較。我不粘貼也不摘抄,完全是按我自己理解來說,努力做到大白話。

一、synchronized原理

說原理之前先說synchronized4個狀態,因爲不同狀態的實現原理不同。鎖的狀態分爲無鎖->偏向鎖->輕量級鎖->重量級鎖

①無鎖狀態

初始化時候狀態

②偏向鎖

當只有一個線程進入synchronized塊,沒有競爭的情況,就進入偏向鎖狀態。該線程只有第一次進入時候纔會需要同步操作,後續就不需要同步操作,這也是java對synchronized優化操作。

③輕量級鎖

當有2個線程同時請求synchronized塊,那麼java並不會馬上變爲重級鎖,而是用輕量鎖。輕量鎖原理就是cas實現的自旋鎖。

④重量級鎖

當線程大於2或者輕量鎖自旋次數達到一定次數,synchronized會轉變爲重級鎖。這裏要說一個東西,每個對象都有一個對象頭,對象頭裏有一個markdown的東西,這個東西里頭指向一個monitor(每個對象都有一個獨立的monitor),這個monitor裏頭有個valatile的int。當第一個線程進入時候會把這個int置1,重入時候會再加1,其餘線程判斷只要!=0就說明有線程佔用了該鎖。

二、lock原理

首先lock分爲公平鎖和非公平鎖,默認是非公平。公平和非公平區別就是是否可以插隊。

 

lock也有一個valatile的state(int 類型),cas給state置1,並且記錄下當前線程(用於重入鎖判斷)。重點是acquire這個方法。我們重點看看。

這個截圖是在aqs裏,說明lock原理用到了aqs(aqs就是JUC的併發框架,分爲共享和獨佔,lock用的是共享模式)。lock在這裏重寫了tryacquire方法,acquireQueued方法是加入隊列,exclusive是獨佔的意思,說明以獨佔方式如隊列。先來看看tryacquire方法。

裏頭實現非常簡單,第一個if和上面一樣進行一次cas,第二個if是重入鎖的處理。

釋放鎖時候會喚醒隊列第一個元素,然後再進行上述操作,這裏就不貼圖了。

三、一些東西的區別

①synchronized和lock區別

synchronized是關鍵字,lock是工具包。這就註定了lock有更多的功能

②sleep和wait的區別

sleep是Thread的方法只會讓出cpu並不會讓出鎖,而wait2個都讓出

③wait和await區別

notifyall無法控制喚醒wait的執行順序,但是lock可以new多個condition,也就是說可以用condition喚醒你要喚醒的await

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章