The Fresh Synchronization
-
Sometimes I come across code that is just astoundingly crazy. This representative line (it's Java) was my find yesterday in one of the more obscure parts of our codebase:
synchronized (id.toString()) {
The comments nearby indicate that it used to synchronize on
id
but that caused hangs. Well, the code doesn't hang any more!
The only implementation of the type of
id
has thetoString()
method below. No, it doesn't intern anything. ThetoUri
method is uninteresting beyond the fact that it doesn't cache, but rather makes anew each time. This part is non-WTF-y.public String toString() { return toUri().toASCIIString(); }
-
The good news is this code will never deadlock. Excellent performance!
I had to do a double-take on that
synchronized
bit. Never seen anyone synchronize on the result of a method call... and this certainly is a good example of what not to do.
-
The good news is this code will never deadlock. Excellent performance!
It'd get better performance by not locking in the first place, especially as the computation of the string is itself expensive.
-
It'd get better performance by not locking in the first place
If I read that correctly, then I have good news for you.
-
As much as I like Java, I think the decision to allow programmers to synchronize on any object was a bad one. Similarly for adding
wait
,notify
and so on to the baseObject
class, where those features should have been assigned specifically to a specialized utility class.
-
As much as I like Java, I think the decision to allow programmers to synchronize on any object was a bad one. Similarly for adding
wait
,notify
and so on to the baseObject
class, where those features should have been assigned specifically to a specialized utility class.
What’s even more confusing is that Java also provides dedicaced synchronization objects (Lock, Condition), which also inherit from Object (obviously) and thus get the standard lock/monitor interface.
On Lock objects, you need to uselock.lock()
andlock.unlock()
and never usesynchronize
; on Condition objects, you need to callcond.await()
instead ofcond.wait
, andcond.signal()
instead ofcond.notify()
. If you mix these up, it won’t work correctly.
-
Lock objects didn't exist until Java 1.5 in 2005ish. They were introduced at the same time a bunch of other synchronization tools were introduced (including the various thread-safe collection variants).
-
Yes, the later introduction of the dedicated Lock classes to give programmers better control over synchronization was a cautionary tale.