I write some code like this:
public static void function7() {
String str = "123";
String str2 = "123";
synchronized (str) {
if(str != null) {
str2 = "123";
}else{
str = "456";
}
System.out.println(str2);
}
}
The code compile well. But a plugin of Eclipse, Find bugs, give the follow error report:
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.
What exactly it means?
String literals are immutable and shared via the VM's String pool. This means that every time you write, for example, "foo"
, a new String representing foo
is not placed on the heap. As a result, this String pool is visible to all threads. Synchronizing on a String literal then exposes you to unstructured synchronization, which is the first stop on the deadlock hell train.
Efficient sharing of Strings is why you shouldn't use the String constructor with the signature String(String) unless you have a really, really good reason for doing so.
Also, there's no point synchronizing on a local variable, since there's no visibility of it outside of the method, let alone in other threads.
Finally, do you really need to synchronize? Since you're not using it effectively in the code above, even excluding the string issue, it's possible you don't have to use it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With