views:

1258

answers:

4

I was looking through a Findbugs report on my code base and one of the patterns that was triggered was for an empty synchronzied block (i.e. synchronized (var) {}). The documentation says:

Empty synchronized blocks are far more subtle and hard to use correctly than most people recognize, and empty synchronized blocks are almost never a better solution than less contrived solutions.

In my case it occurred because the contents of the block had been commented out, but the synchronized statement was still there. In what situations could an empty synchronized block achieve correct threading semantics?

+9  A: 

An empty synchronized block will wait until nobody else is using that synchronizer. That may be what you want, but because you haven't protected the subsequent code in the synchronized block, nothing is stopping somebody else from modifying what ever it was you were waiting for while you run the subsequent code. That's almost never what you want.

Paul Tomblin
side note: I would definitely replace the concept of empty synchronize block with one of the java.util.concurrent classes. Locks/Barries/Latches all work well for this and the meaning is always explicit from the use (as opposed to magical emtpy braces)
basszero
+3  A: 

It used to be the case that the specification implied certain memory barrier operations occurred. However, the spec has now changed and the original spec was never implemented correctly. It may be used to wait for another thread to release the lock, but coordinating that the other thread has already acquired the lock would be tricky.

Tom Hawtin - tackline
Like a poor man's CountDownLatch?
sk
A very poor and confused man. :)
Tom Hawtin - tackline
A: 

For an in depth look into Java's memory model, have a look at this video from Google's 'Advanced topics in programming languages' series: http://www.youtube.com/watch?v=1FX4zco0ziY

It gives a really nice overview of what the compiler can (often in theory, but sometimes in practice) do to your code. Essential stuff for any serious Java programmer!

+2  A: 

Synchronizing does a little bit more than just waiting, while inelegant coding this could achieve the effect required.

From http://www.javaperformancetuning.com/news/qotm030.shtml

  1. The thread acquires the lock on the monitor for object this (assuming the monitor is unlocked, otherwise the thread waits until the monitor is unlocked).
  2. The thread memory flushes all its variables, i.e. it has all of its variables effectively read from "main" memory (JVMs can use dirty sets to optimize this so that only "dirty" variables are flushed, but conceptually this is the same. See section 17.9 of the Java language specification).
  3. The code block is executed (in this case setting the return value to the current value of i3, which may have just been reset from "main" memory).
  4. (Any changes to variables would normally now be written out to "main" memory, but for geti3() we have no changes.)
  5. The thread releases the lock on the monitor for object this.
Pool