transient和volatile兩個關鍵字一個用於對象序列化,一個用於線程同步,都是Java中比較高階的話題,簡單總結一下。優化
transientspa
transient是類型修飾符,只能用來修飾字段。在對象序列化的過程當中,標記爲transient的變量不會被序列化。線程
示例:對象
當類Test的實例對象被序列化(好比將Test類的實例對象 t 寫入硬盤的文本文件t.txt中),變量 a 的內容不會被保存,變量 b 的內容則會被保存。內存
參考:
把一個對象的表示轉化爲字節流的過程稱爲串行化(也稱爲序列化,serialization),從字節流中把對象重建出來稱爲反串行化(也稱爲爲反序列化,deserialization)。transient 爲不該被串行化的數據提供了一個語言級的標記數據方法。同步
volatile
volatile 也是變量修飾符,只能用來修飾變量。volatile修飾的成員變量在每次被線程訪問時,都強迫從共享內存中重讀該成員變量的值。並且,當成員變量發生變 化時,強迫線程將變化值回寫到共享內存。這樣在任什麼時候刻,兩個不一樣的線程老是看到某個成員變量的同一個值。it
在此解釋一下Java的內存機制:io
Java使用一個主內存來保存變量當前值,而每一個線程則有其獨立的工做內存。線程訪問變量的時候會將變量的值拷貝到本身的工做內存中,這樣,當線程對本身工做內存中的變量進行操做以後,就形成了工做內存中的變量拷貝的值與主內存中的變量值不一樣。class
Java語言規範中指出:爲了得到最佳速度,容許線程保存共享成員變量的私有拷貝,並且只當線程進入或者離開同步代碼塊時才與共享成員變量的原始值對比。效率
這樣當多個線程同時與某個對象交互時,就必需要注意到要讓線程及時的獲得共享成員變量的變化。
而volatile關鍵字就是提示VM:對於這個成員變量不能保存它的私有拷貝,而應直接與共享成員變量交互。
使用建議:在兩個或者更多的線程訪問的成員變量上使用volatile。當要訪問的變量已在synchronized代碼塊中,或者爲常量時,沒必要使用。
因爲使用volatile屏蔽掉了VM中必要的代碼優化,因此在效率上比較低,所以必定在必要時才使用此關鍵字。