synchorized 的使用介紹

背景:給智能櫃加上鎖,保證多個用戶同時存物的時候,不會出現多個人打開同一個智能櫃門的情況

synchorized介紹:synchorized包含兩個部分,一個是鎖,一個是被鎖的內容

當多個線程到達synchorized時,會判斷他的鎖,如果該鎖正在使用中,那麼他就要等待使用的人用完了纔可以用該鎖進去,沒被使用的話則可以直接訪問。

PS:使用鎖需要注意的是鎖不能有多個。即鎖之間要全等。例如A、B同時訪問鎖內容,需要保證鎖一樣纔會排隊。例如A的鎖是字符串“a”,B的鎖也是字符串“a”,如果“a”=="a",那麼就會排隊,如果兩個“a”是兩個對象則不會排隊

鎖的幾種用法,

鎖的位置 鎖的內容 例子
普通方法上 類實例對象 該普通方法
public synchronized String getLocker(Long smartarkId){
//方法正文
}
靜態方法上 類本身 該靜態方法 public static synchronized String getLocker(Long smartarkId){
//方法正文
}
代碼塊上 括號內的內容 大括號內的內容
synchronized (LockerPool.getInstance().getLocker(smartarkId)){
//鎖的內容
}

當synchorized加在方法上面,那麼鎖就是該實例對象(new了多少個對象就有多少個鎖),如果兩個線程的實例對象一致的話,那沒就會排隊

當synchorized加在靜態方法上,那麼鎖就是該類本身(一把鎖),不論實例有多少個,都會排隊。

當synchorized加在對象上,那麼鎖就是該對象(小括號內的內容)。如果小括號裏面的是類,就是類鎖,全局一個(this.getClass或者LockerPool.class,this.getClass獲取當前類,類名.class獲取指定類)。如果小括號裏面的是實例對象,那就是實例鎖,(this)

 

正確示範:

示範一:

第一步,設置鎖

第二步,需要加鎖的內容加上鎖

如上所示,使用的類本身作爲鎖,保證獲取smartarkMap爲同一個,再用smartarkMap作爲鎖保證每個智能櫃打開的時候都會排隊依次打開

運行結果

示範二:

第一步設置鎖

需要加鎖的內容上鎖

下圖是鎖的實現,使用的單例模式下的類實例對象

 

如上所示,我設置了鎖池smartarkMap記錄全部的鎖,同時爲了防止LockerPool出現多個,我設置了單例。爲了防止用戶獲取鎖的時候出現同步,我在獲取鎖的方法上也加了鎖(這個鎖是LockerPool,鎖的內容就是getLocker方法)

使用jmeter進行測試,同時調用7次該接口

可以看出,當第一個線程結束時已經有3個進程進來了,但是他們都等到第一個進程進去以後纔開始開箱,數據庫也保證了每個箱子都沒有重複打開。該測試重複了20次,每次都是同時調用7次接口,未出現重複情況

PS:本來打算計劃寫錯誤方法的,寫了一種後,想想錯誤的還是不要寫詳細了,說說吧。剛開始synchorized我是加在serviceimpl裏面的,多次運行時有概率出錯,加在controller後未出現該情況(或許是serviceimpl運行結束了但是還未存放到數據庫?)synchorized後面的獲取實例方法未加鎖,導致運行時出現同時調用該方法,同時進去鎖的內容裏面的情況

 

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