[concurrency-interest] AtomicReferenceFieldUpdater vs Unsafe

Boehm, Hans hans.boehm at hp.com
Mon Nov 28 14:23:07 EST 2011


There's another problem with tryLock()-like methods, which I pointed out in a 2007 PPoPP paper.  I think the current j.u.c.tryLock() is not correctly specified.  The problem is illustrated by the following badly designed code:

Thread 1:
x = 17;
l.lock();

Thread 2:
while (l.tryLock()) l.unlock();
... x ...  // x should be 17 here!

Effectively this inverts the sense of the lock.  Thread 2 can only proceed after thread 1 acquires the lock.

The problem is that:

- There are no potentially concurrent accesses to x in a sequentially consistent execution of this code, and hence there should be no data races
- The Java memory model does not in fact guarantee that x is 17 in thread 2, because there is a data race by Java memory model definitions.  This race is too hard to explain.
- In order to ensure that x is actually 17, we would need to prevent reordering of the two lines of thread 1.  This is expensive on something like PowerPC, and doesn't benefit well-written code.

A solution, more or less adopted by C++11, is to specify tryLock() as allowing spurious failures, even though the implementation really doesn't.  That has the benefit that it makes it clear why there is a race for code like the above, and it provides an intuitive explanation of which tryLock() uses are really safe, and which are not.

Hans




More information about the Concurrency-interest mailing list