本文整理自《JAVA高併發編程詳解》,汪文君 著
1. 使用上的區別
- volatile關鍵字只能用於修飾實例變量或者類變量,不能用於修飾方法以及方法參數和局部變量、常量等。
- synchronized關鍵字不能用於對變量的修飾,只能用於修飾方法或者語句塊。
- volatile修飾的變量可以爲null,synchronized關鍵字同步愉快的monitor對象不能爲null。
2.對原子性的保證
- volatile無法保證原子性
- 由於synchronized是一種排他的機制,因此被synchronized關鍵字修飾的同步代碼是無法被中途打斷的,因此其能夠保證代碼的原子性。
3.對可見性的保證
- 兩者均可以保證共享資源在多線程間的可見性,但是實現機制完全不同。
- synchronized藉助於JVM指令 monitor enter 和 monitor exit 對通過排他對方式使得同步代碼串行化,在 monitor exit 時所有共享資源都會被刷新到主內存中。
- 相比與synchronized關鍵字, volatile使用機器指令(偏硬件)“lock;”的方式迫使其他線程工作內存的數據失效,不得不到主內存中去再次加載。實現數據同步。
4.對有序性的保證
- volatile 關鍵字禁止JVM編譯器以及處理器對其進行重排序,所以它能夠保證有序性。
- 雖然synchronized關鍵字所修飾的同步方法也可以保證順序性,但是這種順序性是以程序的串行化執行換來的,在synchronized關鍵字修飾的代碼塊中代碼指令也會發生指令重排序的情況。
5.其他
- volatile 不會使線程陷入阻塞。
- synchronized關鍵字會使線程進入阻塞狀態。