在Java文档中,它说在下面的示例中,条件为true:
String a = new String("ABC"); String b = new String("ABC"); if (a.intern() == b.intern()) { .... }
我想知道,考虑到这一点是否仍然成立,a并b以不同Threads或什至不同的方式定义ClassLoaders?
a
b
Threads
ClassLoaders
当我需要根据实体名称来同步加载某个配置的块的功能时,这个问题就出现了,所以我想做些类似的事情:
synchronized (entityName.intern()) { }
我不确定这是否是一个好习惯,所以我可能不会遵循这个方向-但这个问题仍然让我感兴趣。
如果在不同的 线程上 ,是,则条件为true。
如果在不同的 类加载器上 ,我不会指望条件为真。(但是您是否真的在String使用不同的类加载器加载两个副本?)文档说,intern是String使用自己的缓存在中实现的。从String#intern文档中:
String
intern
String#intern
返回字符串对象的规范表示。 该类 最初 由一个 空的字符串池来维护 。 String
返回字符串对象的规范表示。
该类 最初 由一个 空的字符串池来维护 。 String
(我的重点)
因此,如果您以某种方式String使用不同的类加载器两次加载了该类(我不确定您会怎么做,但是我敢肯定有办法),那么这两个String类在 理论上 都将拥有自己的缓存。但是,一个实现可能没有那么好的区别。intern是Oracle JVM中的本机方法,使用以C ++实现的符号表。我还没有足够深入地了解逻辑,以了解在您谈论的极端情况下String,同一JVM中的两个实例是否共享同一符号表。但是到那时,我们正在研究实现方案,它可能会有所不同。该 文件 建议不,他们不会是相同的字符串。