簡體   English   中英

String.intern() 線程安全有保證嗎?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM