[concurrency-interest] How bad can volatile long++ be?

Thomas Hawtin Thomas.Hawtin at Sun.COM
Mon Dec 10 16:06:37 EST 2007


Boehm, Hans wrote:
> In Java, ++ on volatiles is not atomic.  I strongly recommend against maintaining even statistical counters that way.  Use either java.util.concurrent.atomic.AtomicLong or per-thread counters.
> 
> The following non-Java anecdote from several years ago convinced me of this:

So, before java.util.concurrent?

> Our conservative garbage collector used to optionally maintain approximate counts of live objects this way, by having each GC thread increment a shared counter as it found a live object.  There are as many GC threads as processors.  After observing some misbehavior on a dual processor (2 sockets, 1 core/socket) machine, and tracking down what was going on, I discovered that:
> 
> 1) Maintaining the shared counter slowed down the collector by about a factor of two, negating the benefit of running on two processors.
> 
> 2) The final count was consistently off by about a factor of two.
> 
> The cause for (1) was no doubt contention on the cache line containing the counter.  As a result of that, both threads spent a lot of their time waiting on that cache line, and presumably the timing worked out such that there was a high probability the line got stolen between the load and the store of the ++, resulting in the loss of about half the updates.

I don't think AtomicLong is going to help there, as it is still sharing 
a volatile. So thread-local (ThreadLocal) counters are presumably the 
way to go, possibly using an unshared AtomicLong.

Tom Hawtin


More information about the Concurrency-interest mailing list