Java Concurrency Bugs #2 – what to synchronize on
Following up on my previous post, this is the second installment of Java Concurrency Bugs. In this post, we’ll look at bugs that come from synchronizing on the wrong object.
#1: Don’t synchronize on an object you’re changing
synchronized(foo) {
foo = …
}
If you do this, then other threads will be synchronizing on a different object than the thread modifying foo. And if those threads are synchronizing on different objects, then you’re getting no mutual exclusion, which presumably was your intention.
#2: Don’t synchronize on a String literal
private static final String LOCK = “LOCK”;
…
synchronized(LOCK) {
….
}
This looks quite harmless and it may even work fine, but it’s also dangerous. All string literals are interned, so any other component or library in the JVM locking on another (apparently different) string literal “LOCK” will be sharing a lock with this code. This problem does happen in the wild.
If you need an object to lock on and you don’t have any other pre-existing object that makes sense, it’s recommended to just use a new Object().
#3: Don’t synchronize on auto-boxed values
The JLS requires that certain ranges of literals always return the same instance when boxed. Thus locking on a boxed Integer(1) (not a new Integer(1)) will be locking against the same boxed Integer anyone else in the JVM could be using. This is effectively the exact same scenario as #2 – an innocuous-looking lock object could actually be the exact same instance used elsewhere, thus sharing a lock that should be separate.
#4: Don’t synchronize on null
This should be a no-brainer but it can happen. This one’s easy to find though since you’ll get an NPE.
#5: Don’t synchronize on a Lock object
It’s not that you can’t do this but it’s more that it’s probably not what you intended. If you’re synchronizing on a ReentrantLock instance, you probably really want to be calling Lock.lock() instead.
#6: Don’t synchronize on getClass()
In an inheritance hierarchy, it’s possible to fall into the trap of calling getClass() at one point in the hierarchy and believing that this means every class will be synchronizing on the same lock. But if a lower class in the hierarchy runs across this code, you’ll actually be locking on a different lock.
// BAD
synchronized(getClass()) {
…
}
Generally, you probably want something like this instead:
synchronized(Foo.class) {
…
}
#7: Be careful locking on a thread-safe object with encapsulated locking
It can be tempting to believe that locking on an object that is thread-safe will allow you to participate in the same lock. And sometimes you’ll be right. But sometimes you won’t. Unfortunately, the only way to tell is to read the docs and the code.
An example where this will work are the synchronized classes in java.util like Vector and Hashtable. These collections lock internally on the “this” instance itself, thus allowing you to participate externally in that lock if you want. But a class like ConcurrentHashMap does internal locking on objects that are not exposed externally, so it’s not possible to participate in that lock. It’s important to know which situation you’re dealing – if you’re writing a class with encapsulated locking, this is a great thing to document.
Hope that was helpful. If I missed something, let me know…

Hi! My name is Alex Miller and I live in St. Louis. I write code for a living and currently work for
Can you explain the first one? “If you do this, then other threads will be synchronizing on a different object than the thread modifying foo” does not seem true to me.
Why would they be synchronizing on a different object if foo is static? Or is it implied that this is an instance variable? In the static case it’s definitely the same object (which seems like the only use case where anyone would actually synchronize on the object they are trying to modify).
@Josh: If you change foo, then the next thread that comes into the synchronized block (quite possibly before the first thread exits) will see a different instance for foo and synchronize on the new instance. Note I’m not talking about modifying the state inside foo, I’m talking about changing the variable foo to point at a new instance.
One trick for synchronizing on string literals – sometimes I find it useful to give a nice name to a lock (and maybe some tools can display toString() of deadlocked objects) -
private static final String LOCK = new String(“LOCK”);
this is probably only usage of new String(String) which is even remotely useful ;)
Nice writeup. I have a simple and easy to remember approach: declare your synchronization tokens privately and explicitly:
private final Object lock = new Object();
Then the weird edge cases where you’re not locking on your explicitly declared lock stands out like a sore thumb and is a sign of poor encapsulation. (Can’t always be avoided of course).
More here: http://is.gd/hGwV
@Alex – Ah ha, ok. Totally missed that you weren’t doing something like foo.blah but actually reassigning the reference.
Subtle!
.
Probably would have ended up making that mistake though perhaps, so now it’ll definitely be stuck in my head
Number one is a bit misleading. “#1: Don’t synchronize on a variable you’re reassigning” would be better, but not quite spot-on accurate either since you’re synchonizing on the object and not the variable, which is what causes the problem in the first place :)
@Tuure: I don’t think it’s misleading. But it may be badly worded. :) I hear what you’re saying. That’s the benefit of putting this stuff on the web and getting feedback of course. By the time it makes it into a talk I’ll have figured out what the hell I’m talking about. Thanks…
Thanks for sharing these