volatile英文含義爲易變的,是java的一個關鍵字,可以實現同步的部分功能。volatile可以看做輕量級的synchronized。synchronized可以實現同步的可見性和原子性。volatile只可以實現可見性,即保證多線程的每次讀取操作均可以讀到最新的值;因未實現同步的原子性要求,不可用於類似於計數器(++x)這樣的寫操作(讀、寫、存儲)。in short,volatile可以用於的場景如下:
變量的最新狀態不依賴於之前的任一狀態,比如++x即不適用;
該變量也沒有包含在其他變量的不變式中;
可用典型場景:1.狀態標識;2.一次性發布(狀態不再變化);3.傳感器;
文章給出了一種開銷較低的讀-寫同步方式
@ThreadSafe public class CheesyCounter { // Employs the cheap read-write lock trick // All mutative operations MUST be done with the 'this' lock held @GuardedBy("this") private volatile int value; public int getValue() { return value; } public synchronized int increment() { return value++; } }
之所有稱之爲開銷較低是因爲volatile保證了數據的可見性,且允許多個線程同時訪問,比使用synchronized(每次僅允許持有鎖的線程訪問)同步可以獲得更高的共享度,且開銷較低。而寫操作使用synchronized又填補了volatile無法實現原子性導致更新出錯的缺陷。但這種模式也具有volatile的弱點;如果使用不當,會造成錯誤。
綜上,volatile是一種脆弱但簡潔的同步機制,如果volatile修飾的變量真正具有——其當前值不依賴於當前及以前任一狀態———這樣的特性,可以提供類似synchronized的效果。由於開銷較小,且代碼簡潔,在讀操作遠遠大於寫操作且遵循以上應用場景,可用volatile標識實現讀的同步;
參考文獻: