String.intern() 线程安全吗

2022-09-04 04:16:54

我想在Java中使用String.intern()来节省内存(使用内部池来存储具有相同内容的字符串)。我从不同的线程调用此方法。这是一个问题吗?


答案 1

对您的问题的简短回答是肯定的。它是线程安全的。

但是,您可能需要重新考虑使用此工具来减少内存消耗。原因是您无法从滞留字符串列表中删除任何完整内容。更好的解决方案是为此创建自己的设施。您所需要的只是将字符串存储在如下所示的位置:HashMap<String,String>

public String getInternedString(String s) {
    synchronized(strings) {
        String found = strings.get(s);
        if(found == null) {
            strings.put(s, s);
            found = s;
        }
        return found;
    }
}

答案 2
  • 当返回不可变的 Java 字符串时,该方法是线程安全的。您不能按原样操作字符串。

  • 文档确实表明它是线程安全的。(通过强调任何)

因此,对于任何两个字符串 s 和 t,s.intern() == t.intern() 为真,当且仅当 s.equals(t) 为真。

  • 第三,JNI接口使用C语言。 是其中之一,并且根据定义都是不可变的。因此,在原生c级上,我们也保留了线程安全性。jobjectjstringjobject

命名这些,我们有充分的理由说它是线程安全的。

附言:但是,如果使用多个类装入器,则最终可能会遇到具有挑战性的结果,因为字符串池是按 维护的。String-class

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