Forum Controls
Spotlight Features

The Rich Engineering Heritage Behind Dependency Injection

Andrew McVeigh takes us on a tour of the rich heritage behind dependency injection, what it represents, and tells us why its here to stay.

NetBeans 6: Matisse Updates

NetBeans 6 delivers great updates to the Matisse GUI builder. Spend a few minutes with Roman Strobl and get an expert briefing on what's new and what has changed.

Introduction to Groovy Part 3

In this, the third and final installation of Andres' Introduction to Groovy series, you learn about how Groovy handles variable numbers of arguments, named parameters, currying, and more about Groovy operators. Including, some new operators.

Easier Custom Components with Swing Fuse

Swing Fuse (actually just Fuse), is a framework designed to make it easier to create your own custom desktop components. In this article, Daniel Spiewak shows you how to get started and provides sample source code you can download.

Benchmark Analysis: Guice vs Spring

Willam Louth shows how he uses JXInsight Probes to investigate probable performance issues with code bases that he is not familiar with. He also highlights possible pitfalls in creating a benchmark, as well as in the analysis of results.
Replies: 12 - Pages: 1  
Threads: [ Previous | Next ]
  Click to reply to this thread Reply

Don't use String literals for the synchronized blocks!

At 7:08 AM on May 29, 2007, Jochen Bedersdorfer DeveloperZone Top 100 wrote:

Code that is using String literals to synchronize on is dangerous.
See the example below:

class Foo  {
  static private final String LOCK = "LOCK";
  void someMethod() {
    synchronized(LOCK) {
    ...
    }
  }
}

Why is this dangerous? I have a nice private String which is mine and mine alone? Or is it? ;) No, it isn't!

Recall section 3.10.5 of the Java Language Spec 2.0:
It says among other things:
"Literal strings within different classes in different packages likewise represent references to the same String object."

For the code above this means that any number of foreign classes can contain the same literal which translates to the same object, hence creating potential dead-lock situations!
This is also true for Strings for which you call the intern() method!

And this is not only a nice theory, something like this really happened between our code and code in the Jetty library. Both sections used the same string literal above to synchronize critical code sections. The two code segments created a dead-lock with very puzzling stack traces :)
(The Jetty-Bug has been reported already, btw, Jetty-352)

If you really need an object for locking purposes, just create a new Object() to lock on.
Also consider various alternatives, namely using this or facilities in the java.util.concurrent package.

Cheers,
Jochen
1 . At 5:44 PM on May 31, 2007, Mr Magoo wrote:
  Click to reply to this thread Reply

Re: Don't use String literals for the synchronized blocks!

DUH?

This was my first reaction as everyone knows that literals are interned. But then I thought about it and realised that you might miss the connection in a flurry of coding.

So good post :), especially since jetty have made this error themselves. Maybe the guys at "find bugs" and others should be told about this? Or maybe they know?
[..checking...]
nope... :) Find Bugs does not pick it up.

Guess they should be told!
2 . At 6:06 AM on Jun 3, 2007, Jakob Jenkov DeveloperZone Top 100 wrote:
  Click to reply to this thread Reply

Re: Don't use String literals for the synchronized blocks!

Well, this goes for primitive objects too then, right? Integer, Long, Float, Double, Short, Character etc. are all immutable, so the same rules probably apply to them... that the VM can share the same instances across objects.

Integer e = 1;
synchronized(e){

}
jenkov.com - open source, tutorials etc.
3 . At 1:39 PM on Jun 3, 2007, Alen Vrecko wrote:
  Click to reply to this thread Reply

Re: Don't use String literals for the synchronized blocks!

Yeah, If there is no new keyword present then one will most probably be in a lot of troubles.

For numbers autoboxing has one more nasty surprise.

   Integer i1 = 100;
   Integer i2 = 100;
   Integer i3 = 1000;
   Integer i4 = 1000;
   System.out.println(i1==i2);
   System.out.println(i3==i4);


the output

true
false


since certain ranges of values are stored as immutable objects by the Java Virtual Machine.

I personally don't like autoboxing that much. It could be avoided entirely if there would be no primities. But that is another story.

Number num = 123.sqrt();
4 . At 6:14 PM on Jun 3, 2007, Bas Leijdekkers wrote:
  Click to reply to this thread Reply

Re: Don't use String literals for the synchronized blocks!

IntelliJ IDEA will have an inspection "Synchronization on a String object" starting with the next EAP build for version 7.0

Bas
5 . At 12:16 AM on Jun 4, 2007, Syed Shafi wrote:
  Click to reply to this thread Reply

Re: Don't use String literals for the synchronized blocks!

Alen Vrecko,can u please explain the cause why (i3==i4) resulted to false.
6 . At 3:48 AM on Jun 4, 2007, Rich wrote:
  Click to reply to this thread Reply

Re: Don't use String literals for the synchronized blocks!

Check out section 5.1.7 of the Java Langugage Spec: http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.1.7

It requires that "If the value p being boxed is true, false, a byte, a char in the range \u0000 to \u007f, or an int or short number between -128 and 127, then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2."

So basically the boxed values in those ranges are guaranteed to be interned just like strings. Implementations can choose to cover a greater range if they want to. This leads to some confusing behaviour around identity equals (==) and is another reason why you should typically be using the .equals() method instead.
7 . At 8:51 AM on Jun 4, 2007, William Pugh wrote:
  Click to reply to this thread Reply

Re: Don't use String literals for the synchronized blocks!

Just added to FindBugs
8 . At 10:38 AM on Jun 4, 2007, Alen Vrecko wrote:
  Click to reply to this thread Reply

Re: Don't use String literals for the synchronized blocks!

Off topic, the autoboxing stuff:

The code example was from this article a good read.

But by far the most exotic autoboxing wackiness I have ever seen would be "Zero does not always equal zero" as explained here
9 . At 12:21 PM on Jun 4, 2007, William Pugh wrote:
  Click to reply to this thread Reply

Re: Don't use String literals for the synchronized blocks!

Found another occurrence in jetty-6.1.4rc0

Although jetty-352 fixed the issue in one file, it missed it in another file, as found by FindBugs:

M M DL: Synchronization on shared constant could deadlock in org.mortbay.jetty.security.Credential$MD5.digest(String) At Credential.java:[line 185]
10 . At 5:44 PM on Jun 4, 2007, Jonas Larsen wrote:
  Click to reply to this thread Reply

Re: Don't use String literals for the synchronized blocks!

Good point. I agree: Don't use String-literals for synchronized blocks, instead use new Object().

Non-literal String-variables on the other hand, may be very useful. Just make sure that they aren't "easy-to-guess". One simple trick is to prefix the String with the packagename: "com.acme.productX.module1.mystringvalue". (This of course may be done with String literals too, but I recommend using a new Object() instead.)

E.g. when creating cache-functionality, I often synchronize on a unique String-value, calculated by a function which takes some input key-variables, and with an explicit call the intern()-function. Code example:

synchronized (calcUniqueStringId(keyVariable1, keyVariable2).intern()) {
  Data data = getCachedData(calcUniqueStringId(keyVariable1, keyVariable2));
  if (data!=null) return data;
  data = getSomeData(keyVariable1, keyVariable2);
  setCachedData(calcUniqueStringId(keyVariable1, keyVariable2), data);
  return data;
}


Regards,
/Jonas
11 . At 4:32 AM on Jun 12, 2007, Jochen Bedersdorfer DeveloperZone Top 100 wrote:
  Click to reply to this thread Reply

Re: Don't use String literals for the synchronized blocks!

Thanks for the feedback, everybody.
Big thanks to Jan Kümmel for actually detecting the Jetty bug in the first place! Well done.
12 . At 4:55 AM on Jun 20, 2007, GoostleeK wrote:
  Click to reply to this thread Reply

Re: Don't use String literals for the synchronized blocks!

> ...can u please explain the cause why
> (i3==i4) resulted to false.

Integer i = 100; //will be translated by compiler to Integer i = Integer.valueOf(100);

You will get the answer when you look at Integer.valueOf(int) implementation which is:

public static Integer valueOf(int i) {
final int offset = 128;
if (i >= -128 && i return IntegerCache.cache[i + offset];
}
return new Integer(i);
}

thread.rss_message