java - 实习字符串在不同线程和类加载器之间的行为如何?

标签 java string locking thread-safety classloader

在java的文档中,它说在下面的示例中,条件将为真:

String a = new String("ABC");
String b = new String("ABC");

if (a.intern() == b.intern())
{
 ....
}

我想知道,考虑到a时,这是否仍然正确。和b定义在不同的Threads中,甚至不同 ClassLoaders

当我需要能够同步一个基于实体名称加载特定配置的 block 时,这个问题就出现了,所以我想做一些类似的事情:

synchronized (entityName.intern())
{
}

我不确定这是一个好的做法,所以我可能不会追求这个方向 - 但这个问题仍然让我感兴趣。

最佳答案

如果在不同的线程上,是的,条件将为真。

如果在不同的类加载器上,我不会指望条件为真。 (但是你真的使用不同的类加载器加载 String 的两个副本吗?)文档说 intern 是在 String 中实现的,使用它自己的缓存。来自 String#intern documentation :

Returns a canonical representation for the string object.

A pool of strings, initially empty, is maintained privately by the class String.

(我的重点)

因此,如果您以某种方式使用不同的类加载器加载了 String 类两次(我不确定您将如何做到这一点,但我打赌有办法),那么两个 String 理论上,每个类都有自己的缓存。然而,实现可能不会使这一点产生区别。 intern 是 Oracle JVM 中的 native 方法,使用 C++ 实现的符号表。我还没有足够仔细地遵循逻辑,无法确定在您所讨论的边缘情况下,同一 JVM 中的两个 String 实例是否会共享相同的符号表。但到那时,我们正在考虑实现情况,这可能会有所不同。 文档表明不,它们不会是同一个字符串。

关于java - 实习字符串在不同线程和类加载器之间的行为如何?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9294134/

相关文章:

java - 从流加载 log4j

java - 仅替换不是相似字符串子串的字符串?

multithreading - 使用 MVar 在 Haskell 中创建线程安全队列(也许?)

java - 字符串的值对象

string - Pandas 系列 str 链接在一起时替换不起作用

java - 锁.tryLock() : Thread performing different tasks?

ruby-on-rails - 数据库锁在 Rails 和 Postgres 中无法正常工作

java - 将 JButton 设置为另一个 JButton 的位置

java - 可以使用 instanceof 运算符来实现两个并行的函数层次结构和它们的参数吗?

java - 使用 Selenium WebDriver 按下按钮