是否有任何文件证明String.intern()是线程安全的?javadoc暗示它,但不直接处理它:
返回字符串对象的规范表示形式。字符串池最初为空,由类字符串私下维护。 当调用intern方法时,如果池中已经包含了一个与这个字符串对象相等的字符串,则返回来自这个池的字符串。否则,将此字符串对象添加到池中,并返回对此字符串对象的引用。 因此,对于任意两个字符串s和t,s.intern() == t.intern()是真当且仅当s.equals(t)为真。 所有文字字符串和字符串值常量表达式都是内嵌的。字符串文本在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()是线程安全的,上面的代码也很好,但是没有从有信誉的来源直接确认,这让我有点担心。
这里曾多次提出这个问题,但没有提供具体的答复和参考资料:
发布于 2014-02-19 21:27:46
实际上,听起来您可能需要一个番石榴Striped,它以散列的方式将对象映射到锁。如果您正在使用的任何其他代码都有相同的想法,那么对内部字符串的同步似乎是一种潜在的危险的攻击,可能会有奇怪的副作用。
https://stackoverflow.com/questions/21890141
复制相似问题