transient: 修飾的成員變量不會被序列化(serialization)。
volatile: 提示JVM, 對於這個成員變量不能保存它的私有拷貝,而應直接與主內存中共享成員變量交互。
“一個變量聲明爲volatile,就意味着這個變量是隨時會被其他線程修改的,因此不能將它cache在線程memory中。volatile告訴jvm, 它所修飾的變量不保留拷貝,直接訪問主內存中的。Volatile一般情況下不能代替sychronized,因爲volatile不能保證操作的原子性,即使只是i++,實際上也是由多個原子操作組成:read i; inc; write i,假如多個線程同時執行i++,volatile只能保證他們操作的i是同一塊內存,但依然可能出現寫入髒數據的情況。"
synchronized 可以保證可見性和原子性,volatile只保證了可見性,那就是說sychronized可以實現volatile的作用;
但有時不需要考慮原子性,只需保證可見性時,synchronized 的實現就比較複雜,而volatile就簡單明瞭,這時就體現volatile存在性了;
比如說:判斷某個線程是否還需要繼續運行(isStop() or isShutdown())。
另外, 使用volatile關鍵字, 也會觸發Java內存模型裏happens-before的語義。在volatile變量賦值之前(按代碼順序,出現在此變量賦值前的語句一定先被執行),減少confuse.
Volatile使用的情況:
1.運算結果不需要變量的當前值,或者能夠確保只有單一的線程修改變量的值;
2.變量不需要與其他的狀態變量共同參與不變約束;
serialVersionUID
如果你的類Serialized存到硬盤上面後,可是後來你卻更改了類別的field(增加或減少或改名),當你Deserialize時,就會出現Exception的,這樣就會造成不兼容性的問題。
但當serialVersionUID相同時,它就會將不一樣的field以type的預設值Deserialize,可避開不兼容性問題。