volatile關鍵字的作用是強制從公共堆棧中取得變量的值,而不是從線程私有數據棧中取得變量的值。
使用volition關鍵字增加了實例變量在多個線程間的可見性。但volition有個致命的缺點就是不支持原子性。
下面將volition和synchronized關鍵字進行一下比較:
1.volition是線程同步間的輕量級實現,所以volition性能肯定比synchronized性能好,volition只能修飾變量。
2.多線程訪問volition不會發生阻塞,而synchronized會阻塞。
3.volition能保證數據的可見性,而不能保證原子性;而synchronized既可以保證原子性,也可以間接保證可見性。
4.再次強調,關鍵字volition解決的是變量在多個線程之間的可見性;而synchronized關鍵字解決的是多個線程之間訪問資源的同步性。
線程安全包含原子性和可見性兩個方面,java的同步機制都是圍繞這兩個方面來卻保線程安全的。
關鍵字volition主要使用的場合是在多個線程中可以感知共享變量被更改了,並且可以獲得最新的值使用,也就是用多線程讀取共享變量可以獲取最新值使用。
關鍵字volition提示線程每次從共享內存中讀取變量,而不是從私有內存中讀取,這樣保證了數據的可見性。
但是要注意,如果代碼中有i++,也就是i=i+1時,這樣的操作不是一個原子操作,也就是時非線程安全的。具體可以了解下i++的實際意義;
①從內存中讀取變量i
②計算i的值
③將i的值寫到內存中
加如兩個線程同時執行到這段代碼,那有可能就會出現臟數據,解決辦法就是加synchronized字。
其實除了用synchronized,還可以用原子類解決。
這樣可以代替i++,還不要加同步鎖。
另外要說下synchronized關鍵字也能確保數據可見性。
最后學習多線程八字真經“外練互斥,內修可見”。