Java記憶體模型FAQ(八)Final欄位如何改變它們的值
我們可以通過分析String類的實現具體細節來展示一個final變數是如何可以改變的。
String物件包含了三個欄位:一個character陣列,一個陣列的offset和一個length。實現String類的基本原理為:它不僅僅擁有character陣列,而且為了避免多餘的物件分配和拷貝,多個String和StringBuffer物件都會共享相同的character陣列。因此,String.substring()方法能夠通過改變length和offset,而共享原始的character陣列來建立一個新的String。對一個String來說,這些欄位都是final型的欄位。
String s1
=
"/usr/tmp"
;
String s2
= s1
.
substring
(
4
)
;
字串s2的offset的值為4,length的值為4。但是,在舊的記憶體模型下,對其他執行緒來說,看到offset擁有預設的值0是可能的,而且,稍後一點時間會看到正確的值4,好像字串的值從“/usr”變成了“/tmp”一樣。
舊的Java記憶體模型允許這些行為,部分JVM已經展現出這樣的行為了。在新的Java記憶體模型裡面,這些是非法的。
原文
How can final fields appear to change their values?
One of the best examples of how final fields’ values can be seen to change involves one particular implementation of the String class.
A String can be implemented as an object with three fields — a character array, an offset into that array, and a length. The rationale for implementing String this way, instead of having only the character array, is that it lets multiple String and StringBufferobjects share the same character array and avoid additional object allocation and copying. So, for example, the method String.substring() can be implemented by creating a new string which shares the same character array with the original String and merely differs in the length and offset fields. For a String, these fields are all final fields.
//java學習交流:737251827 進入可領取學習資源及對十年開發經驗大佬提問,免費解答!
String s1
=
"/usr/tmp"
;
String s2
= s1
.
substring
(
4
)
;
The string s2 will have an offset of 4 and a length of 4. But, under the old model, it was possible for another thread to see the offset as having the default value of 0, and then later see the correct value of 4, it will appear as if the string “/usr” changes to “/tmp”.
The original Java Memory Model allowed this behavior; several JVMs have exhibited this behavior. The new Java Memory Model makes this illegal.
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70010294/viewspace-2845402/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Java記憶體模型FAQ(九)在新的Java記憶體模型中,final欄位是如何工作的Java記憶體模型
- Java記憶體模型FAQ(一) 什麼是記憶體模型Java記憶體模型
- Java記憶體模型FAQ(五)舊的記憶體模型有什麼問題?Java記憶體模型
- 深入理解Java記憶體模型(六)——finalJava記憶體模型
- Java記憶體模型FAQ(二) 其他語言,像C++,也有記憶體模型嗎?Java記憶體模型C++
- Java記憶體模型(MESI、記憶體屏障、volatile和鎖及final記憶體語義)Java記憶體模型
- Java記憶體模型FAQ(十)volatile是幹什麼用的Java記憶體模型
- Java記憶體模型FAQ(三)JSR133是什麼?Java記憶體模型JS
- Java記憶體模型FAQ(四)重排序意味著什麼?Java記憶體模型排序
- Java記憶體模型FAQ(七)同步會幹些什麼呢Java記憶體模型
- Java的記憶體模型Java記憶體模型
- Java Z 垃圾收集器如何徹底改變記憶體管理Java記憶體
- Java記憶體模型Java記憶體模型
- Java 記憶體模型Java記憶體模型
- JVM記憶體結構、Java記憶體模型和Java物件模型JVM記憶體Java模型物件
- Java記憶體模型FAQ(六)沒有正確同步的含義是什麼?Java記憶體模型
- Java棧溢位|記憶體洩漏|記憶體溢位Java記憶體溢位
- Java記憶體溢位Java記憶體溢位
- Java記憶體區域和記憶體模型Java記憶體模型
- 探索Java記憶體模型Java記憶體模型
- 理解Java記憶體模型Java記憶體模型
- JMM Java 記憶體模型Java記憶體模型
- Java記憶體模型-(1)Java記憶體模型
- Java物件記憶體模型Java物件記憶體模型
- java記憶體模型的實現Java記憶體模型
- Java記憶體模型的基礎Java記憶體模型
- Java記憶體模型是什麼,為什麼要有Java記憶體模型,Java記憶體模型解決了什麼問題?Java記憶體模型
- 淺談JVM記憶體結構 和 Java記憶體模型 和 Java物件模型JVM記憶體Java模型物件
- java記憶體溢位和記憶體洩漏的區別Java記憶體溢位
- mongodb如何改_id欄位?MongoDB
- 淺談Java記憶體模型Java記憶體模型
- Java記憶體模型之前奏Java記憶體模型
- Java記憶體模型簡介Java記憶體模型
- Java記憶體模型 - 簡介Java記憶體模型
- Concurrency(五: Java記憶體模型)Java記憶體模型
- java記憶體模型——重排序Java記憶體模型排序
- 你瞭解Java記憶體模型麼(Java7、8、9記憶體模型的區別)Java記憶體模型
- gson改變輸出欄位的順序