在《synchronized 的另個一重要作用:內(nèi)存可見性》這篇文中,講述了通過同步實現(xiàn)內(nèi)存可見性的方法,在《Volatile 關(guān)鍵字(上)》這篇文中,講述了通過 volatile 變量實現(xiàn)內(nèi)存可見性的方法,這里比較下二者的區(qū)別。
- volatile 變量是一種稍弱的同步機制在訪問 volatile 變量時不會執(zhí)行加鎖操作,因此也就不會使執(zhí)行線程阻塞,因此 volatile 變量是一種比 synchronized 關(guān)鍵字更輕量級的同步機制。
- 從內(nèi)存可見性的角度看,寫入 volatile 變量相當(dāng)于退出同步代碼塊,而讀取 volatile 變量相當(dāng)于進入同步代碼塊。
- 在代碼中如果過度依賴 volatile 變量來控制狀態(tài)的可見性,通常會比使用鎖的代碼更脆弱,也更難以理解。僅當(dāng) volatile 變量能簡化代碼的實現(xiàn)以及對同步策略的驗證時,才應(yīng)該使用它。一般來說,用同步機制會更安全些。
- 加鎖機制(即同步機制)既可以確??梢娦杂挚梢源_保原子性,而 volatile 變量只能確??梢娦?,原因是聲明為 volatile 的簡單變量如果當(dāng)前值與該變量以前的值相關(guān),那么 volatile 關(guān)鍵字不起作用,也就是說如下的表達式都不是原子操作:
count++
、count = count+1
。
當(dāng)且僅當(dāng)滿足以下所有條件時,才應(yīng)該使用 volatile 變量:
- 對變量的寫入操作不依賴變量的當(dāng)前值,或者你能確保只有單個線程更新變量的值。
- 該變量沒有包含在具有其他變量的不變式中。
總結(jié):在需要同步的時候,第一選擇應(yīng)該是 synchronized 關(guān)鍵字,這是最安全的方式,嘗試其他任何方式都是有風(fēng)險的。尤其在、jdK1.5 之后,對 synchronized 同步機制做了很多優(yōu)化,如:自適應(yīng)的自旋鎖、鎖粗化、鎖消除、輕量級鎖等,使得它的性能明顯有了很大的提升。