多線程 - synchronized的對象鎖和類鎖


對象鎖

在 Java 中,每個對象都會有一個 monitor 對象,這個對象其實就是 Java 對象的鎖,通常會被稱為“內置鎖”或“對象鎖”。

類的對象可以有多個,所以每個對象有其獨立的對象鎖,互不干擾。

以下代碼鎖的均是對象鎖:

//對象鎖,鎖的是一個代碼塊
public void test(){
	//do something...
	synchronized(this|object) {
      //當這里鎖的是this,那么和下面的那個方法用的是同一個鎖
	}
	//do something...
}


//對象鎖,鎖的是一個方法
public synchronized void test(){
	//do something...
	//do something...
	//do something...
}

  

 

類鎖

在 Java 中,針對每個類也有一個鎖,可以稱為“類鎖”,類鎖實際上是通過對象鎖實現的,即類的 Class 對象鎖。

每個類只有一個 Class 對象,所以每個類只有一個類鎖。

 

//類鎖,鎖的是一個代碼塊
public void test(){
	//do something...
	synchronized(類.class) {

	}
	//do something...
}


//類鎖,鎖的是一個方法
public static synchronized void test(){
	//do something...
	//do something...
	//do something...
}

  

對象鎖,類鎖,鎖static變量 之間的干擾性

  • 不同的對象鎖,互相不干擾,可以並行
  • 對象鎖和類鎖,互相不干擾,可以並行
  • 鎖static變量很具有迷惑性,其實鎖的還是一個對象,依舊是對象鎖。類鎖只有上述的兩種情況,鎖static變量不是類鎖之一。因此下面兩個方法,依舊可以並行。

 

 錯誤的加鎖和原因分析

synchronized 鎖的對象,要保證是不變的。一旦中途被改變,那么將失去鎖的意義。多線程競爭的就不是同一對象的鎖了。

  

原因:雖然我們對 i 進行了加鎖,但是

 

但是當我們反編譯這個類的 class 文件后,可以看到 i++實際是,

 

 

 

 

本質上是返回了一個新的 Integer 對象。也就是每個線程實際加鎖的是不同 的 Integer 對象。因此並不能起到鎖的作用。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM