Synchronized的語義底層是通過一個monitor(監視器鎖)的對象來完成。
每個對象有一個監視器鎖(monitor)。每個Synchronized修飾過的代碼當它的monitor被占用時就會處於鎖定狀態並且嘗試獲取monitor的所有權 ,過程:
1)如果monitor的進入數為0,則該線程進入monitor,然后將進入數設置為1,該線程即為monitor的所有者;
2)如果線程已經占有該monitor,只是重新進入,則進入monitor的進入數加1(可重入);
3)如果其他線程已經占用了monitor,則該線程進入阻塞狀態,直到monitor的進入數為0,再重新嘗試獲取monitor的所有權。
此處最好結合 java對象在內存中的布局來看。直接上圖:
monitor對象存在於每個Java對象的對象頭中(存儲的是指針),synchronized鎖便是通過這種方式獲取鎖的,也是為什么Java中任意對象可以作為鎖的原因,同時也是notify/notifyAll/wait等方法存在於頂級對象Object中的原因。