2012-02-15 55 views
0

在java中的文檔,它說的是,在下面的例子中,病情會爲真:內部字符串如何在不同線程和classloarders之間運行?

String a = new String("ABC"); 
String b = new String("ABC"); 

if (a.intern() == b.intern()) 
{ 
.... 
} 

我想知道,如果考慮到ab在不同Threads定義,或者即使仍然是正確的不同ClassLoaders

,當我需要加載基於實體的名稱有一定配置的塊同步的能力,這個問題上升,所以我想這樣做:

synchronized (entityName.intern()) 
{ 
} 

我不知道這是一個好的做法,所以我可能不會追求這個方向 - 但這個問題仍然令我感興趣。

回答

3

如果不同線程,是的,條件將是真實的。

如果在不同的類裝載機,我不會指望條件是正確的。 (但是你真的使用不同的類加載器加載String的兩個副本嗎?)文檔說internString中使用它自己的緩存實現。來自String#intern documentation

返回字符串對象的規範表示形式。

最初爲空的字符串池由String類別私人維護

(我的重點)

因此,如果你以某種方式加載String類使用兩次不同的類裝載器(我不知道你會怎麼做,但我敢打賭,有一種方法),那麼兩個String類將各自具有它自己的高速緩存  — 理論。但是,實施可能不會使這種區分成爲可能。 intern是Oracle JVM中的一種本地方法,使用在C++中實現的符號表。我沒有嚴密地跟蹤邏輯,看看在你所談論的邊緣情況下,同一個JVM中的String這兩個實例是否會共享相同的符號表。但在那個時候,我們正在考慮實施,這可能會有所不同。 文檔建議不,它們不會是相同的字符串。

+0

似乎最合乎邏輯的答案,謝謝。 – RonK 2012-02-15 21:07:50

0

是的 - 在整個JVM中進行實習。

如果您通過不同的類加載器加載java.lang.String的多個版本,我會非常關心您的執行環境......實習會是您最擔心的問題。

+0

即使你(用某種方式)使用兩個不同的類加載器加載兩次'String',你確定它是JVM範圍的? – 2012-02-15 13:23:16

+0

@ T.J.Crowder嗯,我很*很確定。我喜歡你的解釋 - 顯示比我的快速繪製+1更多的思考你的答案:) – Bohemian 2012-02-15 13:50:39

相關問題