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. (sponsored)
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.
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.
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.
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.
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.
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.
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.
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;
}
Don't use String literals for the synchronized blocks!
At 7:08 AM on May 29, 2007, Jochen Bedersdorfer
wrote:
Fresh Jobs for Developers Post a job opportunity
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?
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
12 replies so far (
Post your own)
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
[..checking...]
nope...
Guess they should be told!
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){
}
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.
the output
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.
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.0Bas
Re: Don't use String literals for the synchronized blocks!
Alen Vrecko,can u please explain the cause why (i3==i4) resulted to false.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.7It 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.
Re: Don't use String literals for the synchronized blocks!
Just added to FindBugsRe: 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
Re: Don't use String literals for the synchronized blocks!
Found another occurrence in jetty-6.1.4rc0Although 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]
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
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.
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);
}