[英]String.intern() thread safety guaranteed?
是否有任何文件保證String.intern()
是線程安全的? javadoc 提到了它,但沒有直接解決它:
返回字符串對象的規范表示。 字符串池最初是空的,由 String 類私下維護。
當調用 intern 方法時,如果池中已經包含一個等於該 String 對象的字符串(由 equals(Object) 方法確定),則返回池中的字符串。 否則,將此 String 對象添加到池中並返回對此 String 對象的引用。
因此,對於任意兩個字符串 s 和 t,當且僅當 s.equals(t) 為真時,s.intern() == t.intern() 為真。
所有文字字符串和字符串值常量表達式都被實習。 字符串文字在 Java™ 語言規范的第 3.10.5 節中定義。
值得注意的是,javadoc 說保證會返回池中的字符串,但池本身並不是線程安全的(因此,在競爭線程的情況下,它似乎為要替換池條目的大門敞開了大門,雖然我認為這種解釋不太可能)。
String
的 JDK 源顯示intern()
是一個本地方法,它沒有說明其線程安全性:
public native String intern();
我特別關心的是以下是否完全線程安全,保證在面對並發請求時,為每個唯一的字符串值只創建一個MyObject
(而不僅僅是存儲在緩存中):
public void myMethod(String myString)
{
// Get object from cache, the cache itself is thread safe
MyObject object = myCache.get(myString);
if (object == null)
{
synchronized(myString.intern())
{
// Retry cache to avoid race condition
object = myCache.get(myString);
if (object == null)
{
object = new MyObject(myString);
// ... do some startup / config of the object ...
myCache.put(object);
}
}
}
// do something useful with the object
}
我希望避免同步方法或緩存本身,因為創建對象可能需要一些時間(需要網絡訪問)。 有一些解決方法,例如維護本地線程安全緩存/字符串池,但除非必要,否則不值得這樣做。 String.intern()
的內存影響(無法從緩存中刪除內部字符串)與此特定用例(使用少量字符串)無關。
我相信String.intern()
是線程安全的,並且上面的代碼很好,但是缺乏來自信譽良好的來源的直接確認讓我有點擔心。
這個問題以前在這里被問過多次,但沒有提供具體的參考答案:
這實際上聽起來像是您可能想要一個 Guava Striped<Lock>
,它以散列方式將對象映射到鎖。 同步實習字符串似乎是一個潛在的危險黑客,如果您使用的任何其他代碼有相同的想法,它可能會產生奇怪的副作用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.