Java: 在 String 对象上同步

Java: synchronize on String object

我写了一些这样的代码:

public static void function7() {
    String str = "123";
    String str2 = "123";
    synchronized (str) {
        if(str != null) {
            str2 = "123";
        }else{
            str = "456";
        }
        System.out.println(str2);
    }
}

代码编译良好。 但是Eclipse的一个插件,Find bugs,报错如下:

Constant Strings are interned and shared across all other classes loaded by the JVM. Thus, this could is locking on something that other code might also be locking. This could result in very strange and hard to diagnose blocking and deadlock behavior.

具体是什么意思?

字符串文字是不可变的,并通过 VM 的字符串池共享。这意味着每次你写,例如"foo",一个新的代表foo的String并没有放在堆上。结果,这个 String 池对所有线程都是可见的。然后,在 String 文字上进行同步会使您暴露于非结构化同步,这是死锁地狱列车的第一站。

字符串的高效共享是您不应该使用带有签名 String(String) 的字符串构造函数的原因,除非您有非常非常好的理由这样做。

此外,对局部变量进行同步是没有意义的,因为它在方法之外是不可见的,更不用说在其他线程中了。

最后,真的需要同步吗?由于您在上面的代码中没有有效地使用它,即使排除字符串问题,也有可能您不必使用它。