從1.0版本開始,Java中的每一個對象都有一個内部鎖。
将靜态方法聲明為synchronized也是合法的 ,如果調用這種方法,該方法獲得相關的類對象的内部鎖。
synchronized關鍵字經過編譯之後,會在同步塊的前後分别形成monitorenter和monitorexit這兩個位元組碼指令,這兩個位元組碼都需要一個reference類型的參數來指明要鎖定和解鎖的對象。如果Java程式中的synchronized明确指定了對象參數,那就是這個對象的reference;如果沒有明确指定,那就根據synchronized修飾的是執行個體方法還是類方法,去取對應的對象執行個體或class對象來作為鎖對象。
在虛拟機規範對monitorenter和monitorexit的行為描述中,有兩點是需要特别注意到。
1. synchronized同步塊對同一線程來說是可重入的,不會出現自己把自己鎖死的問題。
2. 同步塊在已進入的線程執行完之前,會阻塞後面其他線程的進入。
針對第一點的示例代碼如下:
public classOne{
publicstaticvoidmain(String[] args)
{
Object lock = new Object();
synchronized(lock)
{
System.out.println("第1次進入鎖定區域");
synchronized(lock)
{
System.out.println("第2次進入鎖定區域");
}
}
}
}
參考《深入了解java虛拟機》一書