1. 程式人生 > >Java關鍵字transient和volatile小結

Java關鍵字transient和volatile小結

java pre txt 關鍵字 代碼 字段 代碼優化 class 保存

transient

類型修飾符,只能用來修飾字段。

在對象序列化的過程中,標記為transient的變量不會被序列化。

class Test {

    transient int a; // 不會被持久化

    int b; // 持久化

}

當類Test的實例對象被序列化(比如將Test類的實例對象 t 寫入硬盤的文本文件t.txt中),變量 a 的內容不會被保存,變量 b 的內容則會被保存。

參考:
把一個對象的表示轉化為字節流的過程稱為串行化(也稱為序列化,serialization),

從字節流中把對象重建出來稱為反串行化(也稱為為反序列化,deserialization)。

transient 為不應被串行化的數據提供了一個語言級的標記數據方法。

volatile

變量修飾符,只能用來修飾變量。

volatile修飾的成員變量在每次被線程訪問時,都強迫從共享內存中重讀該成員變量的值。

而且,當成員變量發生變化時,強迫線程將變化值回寫到共享內存。

這樣在任何時刻,兩個不同的線程總是看到某個成員變量的同一個值。

在此解釋一下Java的內存機制:

Java使用一個主內存來保存變量當前值,而每個線程則有其獨立的工作內存。線程訪問變量的時候會將變量的值拷貝到自己的工作內存中,這樣,當線程對自己工作內存中的變量進行操作之後,就造成了工作內存中的變量拷貝的值與主內存中的變量值不同。

Java語言規範中指出:為了獲得最佳速度,允許線程保存共享成員變量的私有拷貝,而且只當線程進入或者離開同步代碼塊時才與共享成員變量的原始值對比。

這樣當多個線程同時與某個對象交互時,就必須要註意到要讓線程及時的得到共享成員變量的變化。

而volatile關鍵字就是提示VM:對於這個成員變量不能保存它的私有拷貝,而應直接與共享成員變量交互。

使用建議:

在兩個或者更多的線程訪問的成員變量上使用volatile。當要訪問的變量已在synchronized代碼塊中,或者為常量時,不必使用。

由於使用volatile屏蔽掉了VM中必要的代碼優化,所以在效率上比較低,因此一定在必要時才使用此關鍵字。

Java關鍵字transient和volatile小結