我写了这样的代码:
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的插件,查找错误,给出以下错误报告:
常量字符串在JVM加载的所有其他类之间实现并共享。因此,这可能会锁定其他代码也可能锁定的内容。这可能导致非常奇怪且难以诊断阻塞和死锁行为。
究竟是什么意思?
答案 0 :(得分:4)
字符串文字是不可变的,并通过VM的字符串池共享。这意味着每次编写时,例如"foo"
,表示foo
的新String都不会放在堆上。因此,此String池对所有线程都可见。在String文字上同步,然后让你暴露于非结构化同步,这是死锁地狱列车的第一站。
有效共享字符串是你不应该使用带有签名String(String)的String构造函数的原因,除非你有一个非常非常好的理由这样做。
此外,没有必要同步局部变量,因为在方法之外没有它的可见性,更不用说在其他线程中了。
最后,你真的需要同步吗?由于您没有在上面的代码中有效地使用它,即使排除了字符串问题,也可能不必使用它。