1. 設計同步器的意義
多線程中,有可能會出現同一個線程訪問同一個共享資源,我們稱這個資源爲臨近資源,這種資源可以使對象,變量,文件。由於線程訪問的過程不可控,所以需要採用同步機制來協同對象可變狀態的訪問
1.1 如何解決線程併發安全問題
序列化訪問臨界資源。在同一時刻只有一個線程可以訪問臨界資源,也稱作同步互斥訪問。java中提供了倆種方式實現同步互斥訪問 synchronized,lock;
2. synchronized原理詳解
synchronized內置鎖是一種對象鎖,鎖的對象而非引用,作用力度是對象,可重入;加鎖的方式有三種,1同步實例方法,鎖當前實例對象;2同步類方法,鎖的當前類對象;3同步代碼塊,鎖的是括號裏的對象
2.1 synchronized的底層原理
synchronized是基於jvm內置鎖實現,通過內部的monitor(監視器鎖)實現,基於進入退出monitor對象實現方法與代碼同步,monitor的實現依賴底層操作系統的mutex lock(互斥鎖)實現,它是一個重量級鎖,性能低,當然jvm1.5後進行了優化,如所粗化,鎖消除,輕量級鎖,偏向鎖,適應性自旋等減少鎖開銷。內置鎖的性能基本和lock持平。
synchronized關鍵字被編譯成字節碼後會被翻譯成monitorenter和monitorexit倆條指令分別在同步塊邏輯代碼的其實位置與結束位置
2.2 monitor監視鎖
任何一個對象都有一個monitor與之關聯,當一個monitor被持有後,他將處於鎖定狀態;
monitorenter:每個對象都是一個監視器鎖(monitor)。當monitor被佔用時就會處於鎖定狀態,線程執行 monitorenter指令時嘗試獲取monitor的所有權,過程如下他的執行過程如下:
a 如果monitor的進入數爲0 ,則該線程進入monitor,然後進入數設置爲1,該線程既爲monitor的所有者
b 如果線程已經佔有了monitor,只是重新進入,則monitor進入加1
c 如果其他線程佔用了monitor,則該線程進入阻塞狀態,直到monitor的進入數爲0,在嘗試獲取monitor的所有權
monitorexit:執行monitorexit的線程必須對應的monitor持有者,執行指令時,monitor的進入數減一,如果減一後進入數爲0,則線程退出monitor,不再是這個monitor的持有者,其他被這個monitor阻塞的線程可以嘗試進入獲取這個monitor的所有權。
通過上面兩段描述,我們應該能很清楚的看出Synchronized的實現原理,Synchronized的語義底層是通過一個monitor的對象來 完成,其實wait/notify等方法也依賴於monitor對象,這就是爲什麼只有在同步的塊或者方法中才能調用wait/notify等方法,否則 會拋出java.lang.IllegalMonitorStateException的異常的原因。
看一個案例
2.3 什麼是monitor
可以理解成一個同步工具,或者一種同步機制,通常被描述爲一個對象。與一切皆對象一樣,所有的java對象天生的monitor,每一個java對象都有成爲monitor的潛質,因爲java設計中,每一個java對象自產生開始就帶了一把看不見的鎖,它叫內部鎖或者monitor鎖,也就是長說的synchronize對象鎖,markword的鎖標識爲10,其中指針指向的是monitor對象的起始地址。在Java虛擬機(HotSpot)中,Monitor是由ObjectMonitor實現的,其主要數據結構如下(位於 HotSpot虛擬機源碼ObjectMonitor.hpp文件,C++實現的):
3. 對象的內存佈局
hospot虛擬機中,對象在內存中存儲的佈局分爲三個區域,對象頭hearder,實例數據instance data,對其填充 padding
1 對象頭,比如hash嗎,對象所屬的年代,對象鎖,鎖狀態標誌,
2 實例數據,存放類的屬性數據信息
3 對其填充,虛擬機要求對象起始地址必須是8字節的整數倍,只是爲了對齊字節
3.1 對象頭
hotspot虛擬機的對象頭包含倆部分信息,Markword,存儲對象自身的運行時數據,如哈希嗎,gc分代年齡,鎖狀態標誌,線程持有的鎖,偏向線程id,偏向時間戳等它是實現輕量級鎖和偏向鎖的關鍵
3.2 對象頭分析工具
3.3 鎖膨脹升級過程
鎖的狀態總共有四種,無鎖狀態、偏向鎖、輕量級鎖和重量級鎖。隨着鎖的競爭,鎖可以從偏向鎖升級到輕量級鎖,再升級的重 量級鎖,但是鎖的升級是單向的,也就是說只能從低到高升級,不會出現鎖的降級。從JDK 1.6 中默認是開啓偏向鎖和輕量級鎖 的,可以通過-XX:-UseBiasedLocking來禁用偏向鎖。下圖爲鎖的升級全過程:
3.3.1 偏向鎖
3.3.2 輕量級鎖
3.3.3 自旋鎖
3.3.4 鎖消除
3.3.5 逃逸分析