Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: synchronize on String object [duplicate]

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?

like image 756
wuyi Avatar asked May 04 '15 10:05

wuyi


1 Answers

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.

like image 77
Steve Chaloner Avatar answered Sep 20 '22 22:09

Steve Chaloner