首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >String.intern()线程安全保证?

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

Stack Overflow用户
提问于 2014-02-19 19:14:47
回答 1查看 1.6K关注 0票数 6

是否有任何文件证明String.intern()是线程安全的?javadoc暗示它,但不直接处理它:

返回字符串对象的规范表示形式。字符串池最初为空,由类字符串私下维护。 当调用intern方法时,如果池中已经包含了一个与这个字符串对象相等的字符串,则返回来自这个池的字符串。否则,将此字符串对象添加到池中,并返回对此字符串对象的引用。 因此,对于任意两个字符串s和t,s.intern() == t.intern()是真当且仅当s.equals(t)为真。 所有文字字符串和字符串值常量表达式都是内嵌的。字符串文本在Java规范第3.10.5节中定义。

值得注意的是,javadoc表示,池中的字符串肯定会被返回,但不会保证池本身是线程安全的(因此,正如所写的,它似乎为在出现竞争线程时替换池条目打开了大门,尽管我认为这种解释是不太可能的)。

String的JDK源代码显示,intern()是一个本机方法,它不会说明它的线程安全性:

代码语言:javascript
复制
public native String intern();

我所关心的具体问题是,以下内容是否完全线程安全,保证只有一个MyObject创建的(而不仅仅存储在缓存中),用于处理并发请求时的每个唯一字符串值:

代码语言:javascript
复制
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()是线程安全的,上面的代码也很好,但是没有从有信誉的来源直接确认,这让我有点担心。

这里曾多次提出这个问题,但没有提供具体的答复和参考资料:

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-02-19 21:27:46

实际上,听起来您可能需要一个番石榴Striped,它以散列的方式将对象映射到锁。如果您正在使用的任何其他代码都有相同的想法,那么对内部字符串的同步似乎是一种潜在的危险的攻击,可能会有奇怪的副作用

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21890141

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档