Getting a deadlock without using any locks
Josh Block and Neil Gafter gave what was in my opinion the most interesting talk of JavaOne, day 1 on coding puzzles.
Some of the puzzles were the kind where the warning signs go off just as soon as you see them, and the sensible thing is to quit trying to work out what is going on, and just change it to be obvious. For example:
count += count++;
Stop thinking about what it does - ask what it should do and re-write it.
count++; count = count * 2;
Is way clearer, and isn't buggy.
The real gem in the list of puzzles was on avoiding the "lock-free dead-lock" scenario. The following code uses a Thread to do some complex initialization for a class in the background:
public class LazySetup {
private static boolean init = false;
static {
Thread t = new Thread(new Runnable() {
public void run() {
// hard work goes here
init = true;
}
}
t.start();
try {
t.join();
}
catch (InterruptedException ex) {
}
}
public static void main() {
System.out.print(init);
}
}
Apparently there is Swing code that does something similar. You could use an idiom like this to set off an number of setup tasks in parallel; but don't!
The very subtle bug is that the line that says init = true;. Since this line is executing in a different (inner) class and thread from the main LazySetup class and thread, the JVM needs to check to see the status of the Class to see if it is properly initialized.
Clearly it isn't - The main thread is waiting for the the child thread in the t.join(); line, which is inside the static init block. So before the init = true; line is executed the JVM stops execution of this thread to wait for the initialization to finish, which of course will never happen.
Outch! The moral is never use lazy threads to initialize your resources, or if you really need to you should create some separate classes so the init order is clearer.
Security Warning: Watch out using CVS at JavaOne
Very nearly got bit by this one today. I wanted to show someone the DWR code at JavaOne, so I flipped up the the lid on my laptop and was just about to double click on a java class when it occurred to me that doing so would probably be telling someone my password.
Whenever you open a file in a CVS project using Eclipse it checks CVS to see what you have changed compared to the CVS version (the same goes for Intellij as well I think). Since java.net advises you to use pserver for CVS access, this means you password will be being broadcast in clear-text using wifi to 15,000 developers at JavaOne?
How many of those 15,000 developers will be snooping on the network do you think? Anyone want to bet their password on 0?
The good news is that there is a solution, the shame is that java.net don't publicize it more.
I pointed it out to the java.net people, who said, roughly speaking "there is a special 'tunnel' ssh user that can fix the issue". (The lady I was speaking to even spoke in HTML - very impressive!)
It's a bit of a shame that java.net don't publicize this one more, but appatently it has something to do with the 'tunnel' user being a Sun enhancement, and the website descriptions are provided by Colab.net.