Java關鍵字transient和volatile

最近突然對java的源碼中的一些模式很感興趣,今天針對hashmap與hashtable的不同想探尋下原因。

衆所周知,這兩者一個是線程安全、一個線程不安全,但是怎麼實現的呢?就打算看下源碼,看見了裏面有兩個關鍵字的使用,特此搜索mark下。

transient和volatile兩個關鍵字一個用於對象序列化,一個用於線程同步,都是Java中比較高階的話題,簡單總結一下。

transient

transient是類型修飾符,只能用來修飾字段。在對象序列化的過程中,標記爲transient的變量不會被序列化。

參考:
把一個對象的表示轉化爲字節流的過程稱爲串行化(也稱爲序列化,serialization),從字節流中把對象重建出來稱爲反串行化(也稱爲爲反序列化,deserialization)。transient 爲不應被串行化的數據提供了一個語言級的標記數據方法。

volatile
volatile也是變量修飾符,只能用來修飾變量。volatile修飾的成員變量在每次被線程訪問時,都強迫從共享內存中重讀該成員變量的值。而且,當成員變量發生變化時,強迫線程將變化值回寫到共享內存。這樣在任何時刻,兩個不同的線程總是看到某個成員變量的同一個值。

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

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

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

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

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

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

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

標註下轉載位置(http://heaven-arch.iteye.com/blog/1160693

發佈了20 篇原創文章 · 獲贊 0 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章