简体   繁体   English

String.intern() 线程安全有保证吗?

[英]String.intern() thread safety guaranteed?

Is there any documented guarantee that String.intern() is thread safe?是否有任何文件保证String.intern()是线程安全的? The javadoc alludes to it but does not address it directly: javadoc 提到了它,但没有直接解决它:

Returns a canonical representation for the string object.返回字符串对象的规范表示。 A pool of strings, initially empty, is maintained privately by the class String.字符串池最初是空的,由 String 类私下维护。

When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned.当调用 intern 方法时,如果池中已经包含一个等于该 String 对象的字符串(由 equals(Object) 方法确定),则返回池中的字符串。 Otherwise, this String object is added to the pool and a reference to this String object is returned.否则,将此 String 对象添加到池中并返回对此 String 对象的引用。

It follows that for any two strings s and t, s.intern() == t.intern() is true if and only if s.equals(t) is true.因此,对于任意两个字符串 s 和 t,当且仅当 s.equals(t) 为真时,s.intern() == t.intern() 为真。

All literal strings and string-valued constant expressions are interned.所有文字字符串和字符串值常量表达式都被实习。 String literals are defined in section 3.10.5 of the The Java™ Language Specification.字符串文字在 Java™ 语言规范的第 3.10.5 节中定义。

Notably, the javadoc says that a String from the pool is guaranteed to be returned, but not that the pool itself is thread safe (so as written it appears to leave the door open for a pool entry to be replaced in the event of competing threads, although I think this interpretation is unlikely).值得注意的是,javadoc 说保证会返回池中的字符串,但池本身并不是线程安全的(因此,在竞争线程的情况下,它似乎为要替换池条目的大门敞开了大门,虽然我认为这种解释不太可能)。

And the JDK source of String shows intern() to be a native method which does not shed any light on its thread safety: String的 JDK 源显示intern()是一个本地方法,它没有说明其线程安全性:

public native String intern();

My concern is specifically related to whether the following would be fully thread safe, guaranteeing only one MyObject is created (not merely stored in the cache) for each unique string value in the face of concurrent requests:我特别关心的是以下是否完全线程安全,保证在面对并发请求时,为每个唯一的字符串值只创建一个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
}

I wish to avoid synchronizing on either the method or the cache itself since the creation of the object can take some time (entails network access).我希望避免同步方法或缓存本身,因为创建对象可能需要一些时间(需要网络访问)。 There are workarounds such as maintaining a local thread safe cache / pool of strings but it is not worth doing unless necessary.有一些解决方法,例如维护本地线程安全缓存/字符串池,但除非必要,否则不值得这样做。 The memory implications of String.intern() (inability to remove interned strings from the cache) are not relevant for this particular use case (small number of strings being used). String.intern()的内存影响(无法从缓存中删除内部字符串)与此特定用例(使用少量字符串)无关。

I believe that String.intern() is thread safe and that the code above is fine, but the lack of direct confirmation from a reputable source leaves me slightly concerned.我相信String.intern()是线程安全的,并且上面的代码很好,但是缺乏来自信誉良好的来源的直接确认让我有点担心。

This question has been asked here multiple times before, but no concrete answer with references has been provided:这个问题以前在这里被问过多次,但没有提供具体的参考答案:

That actually sounds like you might want a Guava Striped<Lock> , which maps objects to locks in a hashed way.这实际上听起来像是您可能想要一个 Guava Striped<Lock> ,它以散列方式将对象映射到锁。 Synchronizing on interned strings seems like a potentially dangerous hack that could have weird side effects if any other code you're using had the same idea.同步实习字符串似乎是一个潜在的危险黑客,如果您使用的任何其他代码有相同的想法,它可能会产生奇怪的副作用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM