views:

366

answers:

3

I've been debating this to myself for the last few minutes, and I'm seeing reasons for both yes and no. This stemmed from looking at the answers to Java HashMap vs. Hashtable and seeing several people say Hashtable is in fact slower.

It seems to me that a synchronized method should act absolutely no different than its unsynchronized counterpart if running in a single thread, since the action of synchronizing shouldn't block anything. That said, I would imagine the compiler handles the two cases differently and that's why people are saying synchronized is slower.

Not that it's by any means conclusive, but I ran some simple tests on HashMap vs Hashtable, and saw little difference in speed.

+4  A: 

Yes. They are going to be slightly slower due to the extra overhead of maintaining locks.

Mitch Wheat
just ever so slightly. +1
sybreon
... IF the JIT can't decide that it doesn't need to maintain the locks in this case...
Neil Coffey
A: 

When using synchronized data structures, the slowdown is not dependent on "how much" is getting blocked. The act of acquiring or releasing a lock is slow, as it usually involves something like a system call (context switches are slow on any platform). In a JIT environment like a typical JVM, it would theoretically be possible to optimize out all lock/unlock calls when there is only a single thread running, but it would have to be properly invalidated whenever another thread starts up.

Note that things like Linux's futexes don't have to make system calls unless there is contention, but using them is still slower than a no-op.

except if the OS is CPU hot swappable I guess; then the JVM wouldn't be able to make that assumption?
Mitch Wheat
The problem isn't so much whether there are multiple CPUs as whether there are multiple threads inside the JVM. True, being aware of whether there are multiple CPUs would broaden the applicability of this optimization, but it's far more common to run a single threaded app when there are multiple CPUs. The point that I was trying to get across was that I don't know of any mutex analog to zero-cost exceptions.
If the *only* thing your code was doing was acquiring and releasing locks, yes it would be slow. As long as the locks are few enough, any slowdown in your code would be minimal, especially any recent JVM. Uncontended locking is not expensive any longer.
Eddie
+7  A: 

Yes, single-theaded Java programs that use synchronization may be slightly slower than they would be without synchronization. For early Java releases, synchronization was expensive. For any modern release, however, uncontended synchronization is pretty cheap. I wouldn't worry about this.

Note that Java 6 has and Java 7 is to have good optimizations around locking:

  • Lock coarsening
  • Lock elision
  • Adaptive Spin locking
  • Biased locking

For more information, see the Java SE 6 Performance White Paper. Also note that uncontended synchronization appears to be more expensive on multi-core CPUs than on single-core CPUs, perhaps due to the Java Memory Model requirements of synchronization forcing local CPU caches to be shared with other CPUs, or some other memory barrier. For example, read Do Java 6 threading optimizations actually work? - Part II. (The Part I was not as insightful as the Part II.)

Eddie