Java:在 String 对象上同步

标签 java string deadlock synchronized

<分区>

我写了一些这样的代码:

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 池对所有线程都是可见的。然后,在字符串文字上进行同步会使您面临非结构化同步,这是死锁 hell 列车的第一站。

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

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

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

关于Java:在 String 对象上同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30028379/

相关文章:

java - 在 firebase firestore 中获取对象内部的数据?

java - 无法找到/加载 swt-gtk

java - 如何使用 Spring Batch 将 header 和预告片写入现有文件而不覆盖该文件中的信息?

java - 如何在 Android 中使用 firebase admin sdk 使用电子邮件和密码登录

结构打印垃圾中的字符数组

java - 带撇号的字符串的正则表达式

windbg - 排除 COM+ 应用程序死锁故障

c++ - 如何使用 strspn 模仿 std::string find_first_not_of

ios - NSManagedObjectContext - FetchRequest 死锁

sql-server - 删除然后批量插入时 SQL 死锁