在java的文档中,它表示在下面的例子中,条件为真:
String a = new String("ABC");
String b = new String("ABC");
if (a.intern() == b.intern())
{
....
}
我想知道,如果在考虑a
和b
在不同的Threads
或甚至不同的ClassLoaders
中定义时仍然如此?
当我需要能够根据实体的名称同步加载某个配置的块时,这个问题就出现了,所以我想做类似的事情:
synchronized (entityName.intern())
{
}
我不确定这是一个好习惯,所以我可能不会追求这个方向 - 但这个问题仍然让我感兴趣。
答案 0 :(得分:3)
如果在不同的线程上,是的,条件将为真。
如果在不同的类加载器上,我不会指望条件为真。 (但是你真的使用不同的类加载器加载了String
的两个副本吗?)文档说明intern
在String
内使用自己的缓存实现。来自String#intern
documentation:
返回字符串对象的规范表示。
字符串池(最初为空)由班级
String
私下维护。
(我的重点)
所以,如果你以某种方式使用不同的类加载器两次加载String
类(我不知道你会怎么做,但我打赌有一种方法),那么两个String
类会每个都有自己的缓存 - 在理论。但是,实施可能不会那么好。 intern
是Oracle JVM中的本机方法,使用在C ++中实现的符号表。我没有密切关注逻辑,看看在你讨论的边缘情况下,同一个JVM中的String
的两个实例是否会共享相同的符号表。但在那时,我们正在考虑实施,这可能会有所不同。 文档建议不,它们不是相同的字符串。
答案 1 :(得分:0)
是的 - 实习在整个JVM中都有效。
如果您通过不同的类加载器加载多个版本的java.lang.String
,我会非常关注您的执行环境......实习将是您最不担心的问题。