關於synchronized,在java官方文檔上有個很不錯的介紹,這裏簡要小結下:
synchronized語義主要有兩方面的含義:
- 確保同一時刻只有一個線程可以運行synchronized塊中的內容;
- 實現了happens-before語義,即前面進程在synchronized中的修改對後面進程都是可見的(利用acquire和release語義實現,這是內存模型重要概念之一)
具體實現:(以synchronized non-static method爲例)
對於每一個java對象都有一個內在鎖(intrinsic lock),當一個線程訪問一個被synchronized修飾方法時,該線程首先acquire該對象的intrinsic lock,然後在方法返回或者拋出異常的時候release該intrinsic lock,這樣既保證了訪問的唯一性,又保證了該線程的對數據的修改對其他線程都是可見的(happens-before)。
也就是說,一個線程訪問一個對象的synchronized non-static method時,其他所有線程試圖訪問該對象的任何synchronized non-static method(當然也包括synchronized static method)都將被掛起,直到第一個線程訪問結束。
而對於訪問synchronized static method時,由於它並非由一個對象所擁有,所以會將與該類相關聯的 Class Object 的實例進行加鎖,因此此時所有其他打算對synchronized method進行訪問的線程都將被掛起。
此外,synchronized還提供對部分代碼片段進行同步操作,但需要指定其加鎖的Object。
其他資料:
- 在知乎上有一個關於Object和Class這兩個類的一個很有趣的問題
- 在javaworld中有關於在jvm如何實現synchronized的文章