5

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?

Parth Soni
  • 11,158
  • 4
  • 32
  • 54
wuyi
  • 227
  • 1
  • 17
  • See also [Synchronizing on String objects in Java](https://stackoverflow.com/questions/133988/synchronizing-on-string-objects-in-java). – Vadzim Nov 11 '17 at 18:35

1 Answers1

5

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.

Steve Chaloner
  • 8,162
  • 1
  • 22
  • 38
  • 1
    well,I don't think I had use the String constructor with the signature String(String)..... It seems the point is *should not* synchronized an object that may be reused, since this also been pointed by FindBugs. – wuyi May 04 '15 at 11:05
  • @Steve, `String representing foo is not placed on the heap.` are you sure? I don't think so. `foo` is also on heap but in String pool. – Asif Mushtaq Oct 06 '15 at 20:19
  • The location of the String pool is unspecified in the JVM spec; depending on the JVM (and version) you're using, it may or may not be on the heap. – Steve Chaloner Oct 07 '15 at 07:31