Skip to main content

Posts

Double Checked Locking

I still get a lot of questions about whether double-checked locking works in Java, and I should probably post something to clear it up. And I'll plug Josh Bloch's new book, too. Double Checked Locking is this idiom: // Broken -- Do Not Use! class Foo {   private Helper helper = null;   public Helper getHelper() {     if (helper == null) {       synchronized(this) {         if (helper == null) {           helper = new Helper();         }       }     }   return helper; } The point of this code is to avoid synchronization when the object has already been constructed. This code doesn't work in Java. The basic principle is that compiler transformations (this includes the JIT, which is the optimizer that the JVM uses...

Which Lock is Which?

I was at JavaOne last week, and attended Bill Pugh's Defective Java talk. Bill had an important point about what kind of locks you want to be using and what kind you don't, and that point is worth repeating. Bill is, with Dave Hovemeyer, the guy behind FindBugs , which everyone should be using religiously. He was also my graduate advisor; we worked together on the new Java Memory Model. If there are two things Bill knows, they are concurrency and bug patterns. There is a tremendously useful defensive locking discipline that I use all of the time, and recommend that other people use, too: class Foo { private final Object lock = new Object(); private Bar lockProtectsMe; ... public void blah() { synchronized (lock) { // accesses LockProtectsMe... ... } } } This has the following benefits: If you try to acquire the lock on the Foo object instead of the lock, you run the risk that some code outside the class obtains that lock. Perhaps forever . Usi...

Immutability in Java

Another topic that comes up again and again in questions that people ask me is, "How does immutability work in Java"? Immutability is a godsend for concurrent programmers, because you don't have to do lots of sticky reasoning about what threads are updating what variables when, and you don't have to worry about cache thrashing, and you don't have to worry about all sorts of things. When I write concurrent code (which is reasonably often), I try to make as many things immutable as possible. Now, in common parlance, immutability means "does not change". Immutability doesn't mean "does not change" in Java. It means "is transitively reachable from a final field, has not changed since the final field was set, and a reference to the object containing the final field did not escape the constructor". In circumstances other than this, even if a given field is not mutated, the Java memory model requires that there be some form of synchr...

Java Performance Talk

Paul Tyma and I gave a talk at SD West today on Java Performance Myths. The big takeaway was this: Most of the things you think you know about Java performance are really hard to quantify. Write the best code you can. Profile it to find the bottlenecks. Remove the bottlenecks. Rinse and repeat. A couple of other takeaway points here: Don't forget to upgrade every so often. JDK6, for example, runs code compiled for JDK4 just fine, and you get a big performance boost. For free. Memory allocation is pretty cheap. Know that there are three garbage collectors, and know which one is best, when. Read the Java memory management white paper . Hotspot can do lots of things to optimize your locks, but it often doesn't. Having said that, the bottlenecks in concurrent code usually have to do with contention, not synchronization overhead. Use low contention data structures like ConcurrentHashMap to avoid contention, but don't try to get clever with locking. Contrary to popu...

Causality and the Java Memory Model

NB: I started writing this last August, and sent it to a friend of mine for thoughts. I just realized that he never got back to me on it, and I never posted it. I don't much feel like editing it now, so here it is in its original glory Okay, I know. It is nearly impossible to read and understand the causality bits of the Java memory model. That's all that stuff about "Executions and Causality Requirements" on pages 568 – 570 of the Java Language Specification . Bill Pugh, Sarita Adve and I wrote it. Basically, in the last three years, there have been three kinds of reactions to it: ZOMGWTF!? (I'm a normal human being. Give me a break.) This is incomprehensible gibberish. (I'm a pretty smart cookie and I think that everything I can't understand in three seconds is worthless.) Okay, I think I get it, but I have some questions. (I'm a pretty smart cookie and I spent several days trying to understand it.) I find that the last group usually prett...