工作中的點點滴滴-對於鎖的一點兒認識

背景

  最近做一個報表,基礎數據比較大,然後開了3個線程處理,然後分別向Map裏面裏面插入數據,這個的Map用的是HashMap,所以爲了避免多線程安全性問題。需要在HashMap添加數據的地方要加一個鎖。那麼有人來說了,你可以用線程安全的CurrentHashMap啊,那你有沒有思考過在多線程的環境下CurrentHashMap所有的操作都是安全的嗎?這裏對CurrentHashMap安不安全先不展開討論。因爲要用到鎖,所以繞不過去的肯定就synchronized和ReentrantLock。那這兩中鎖從實現的方式上有什麼不同呢,我們一起來了解一下。

首先來先看synchronized,畢竟使用起來簡單嘛哈哈哈哈哈,因爲synchronized是jvm裏面的一個關鍵字,所以如果你想通過常規的查看源碼的方式來弄明白synchronized估計就不行了。所以我們只能通過jdk自帶的工具javap -c [class文件] 來通過字節碼分析。

先放上測試代碼和他對應的字節碼。

1     public void method1() {
2         synchronized (this)
3         {
4 
5         }
6     }

相對於普通方法,我們是不是一眼就可以看出有差別的地方了,那就是在code:5和code:10那裏。根據JVM規範要求,當在執行在執行monitorenter指令的時候,首先要去嘗試獲取對象的鎖,如果這個對象沒有被鎖定,或者當前線程已經擁有了這個對象的鎖,就把鎖的計數器加1,相應地,在執行monitorexit的時候會把計數器減1,當計數器減小爲0時,鎖就釋放了。

通過字節碼我們可以知道synchronized鎖執行過程,那他底層是怎麼來實現的呢?首先在jvm規範中任何一個對象都由三部分組成的,對象頭,數據,填充位。在對象頭中又分爲兩部分,第一部分主要用於儲存對象自身的運行時數據,比如hashCode,GC年齡,鎖信息等。

 

 

 

對象頭的另外一部分是類型執指針,即對象指向他的類元數據的指針。

 

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