1. 程式人生 > >Synchronized關鍵字及鎖物件

Synchronized關鍵字及鎖物件

程式碼示例:

修飾程式碼塊:

 執行結果:

兩個例項分別呼叫test1()方法,程式碼交叉執行,說明Synchronized修飾程式碼塊時,兩個執行緒獲取的鎖不一樣,不同的呼叫物件各自獲取自己的this物件鎖,this代表當前的例項物件。

修飾方法:

兩個例項分別呼叫test2()方法,程式碼交叉執行,說明Synchronized修飾方法時,兩個執行緒獲取的鎖也不是同一個鎖,不同的呼叫物件各自獲取自己的鎖。

 

我們看到,Synchronized修飾程式碼塊和方法時,每個執行緒獲取的鎖都是不同的鎖。在修飾程式碼塊時,鎖物件是

this,this代表當前的例項物件,這裡獲取的鎖叫物件鎖。在修飾方法時,獲取的鎖叫方法鎖。其實,物件鎖和方法鎖是同一個東西,即各自的例項物件。物件鎖(方法鎖)也叫Java的內建鎖,它們三個是一個東西,每個Java的例項物件都是一個實現同步的內建鎖。執行緒進入同步程式碼塊或者方法的時候會自動獲得該鎖,在退出同步程式碼塊或方法時會自動釋放該鎖。獲得內建鎖的唯一途徑就是進入這個鎖保護的同步程式碼塊或方法。

Java內建鎖是一個互斥鎖,即最多隻有一個執行緒能夠獲得該鎖,當執行緒A嘗試去獲得執行緒B持有的內建鎖時,執行緒A必須等待或者被阻塞,直到執行緒B釋放這個鎖。

驗證:

通過結果,我們知道一個執行緒要等另一個執行緒執行完並釋放鎖之後才能執行,因為這兩個執行緒爭搶的是同一個鎖,即

example1這個例項物件。

test1()換成test2()方法,執行結果一樣,即Synchronized修飾程式碼塊和方法時,鎖都是例項物件。

修飾一個類:

修飾靜態方法:

當同一個例項example1在兩個執行緒裡呼叫test1()方法及test2()方法時,結果同上。

我們看到,Synchronized修飾類和靜態方法時,執行結果相同,都是互斥執行。說明他們獲取的鎖是同一個鎖,這個鎖就是類物件,即SynchronizedExample2.class物件。這個鎖叫類鎖,是一個抽象出來的感念,只是為了區別作用於靜態方法與普通方法的情形,因為靜態方法是所有例項共用的,所以對應著

Synchronized修飾的靜態方法的鎖也是唯一的。