In implementing MVCC, I found that the existing
ReadWriteWithUpgradeLock in JBoss Cache was hugely inefficient (lots
of unnecessary syncs) and overkill in the support for readers which I
did not need. Looking around for something a little more "standard",
I considered the j.u.c.locks.ReentrantLock, but found this useless as
well since I need lock owners to be either Threads (if no tx is
running) or a GlobalTransaction instance. Furthermore, due to
replication of events, lock owners should not be compared using
identity (==) but equals() instead (important in the case of
GlobalTransactions owning locks).
So I went about implementing my own lock. After a few attempts using
a concurrent queue and LockSupport.park(), and then fiddling with
o.j.c.locks.AbstractQueuedSynchronizer (and several brainstorming
sessions with Jason), I finally settled on an implementation that does
look good enough. Note that this is *not* a general-purpose lock and
is tied to JBoss Cache, to be able to identify whether the lock to be
acquired needs to be on a Thread or a GlobalTransaction.
Have a look at the OwnableReentrantLock [1]. Apart from containing
minimal syncs and an efficient queueing algorithm thanks to AQS, one
of the other upsells is that it implements Lock, a nice familiar
interface. One benefit here is that if the cache is configured not to
use transactions, we can fall back to a j.u.c.locks.ReentrantLock
instead.
Please have a look at the implementation, comments appreciated.
Cheers
Manik
[1]
http://anonsvn.jboss.org/repos/jbosscache/core/trunk/src/main/java/org/jb...
--
Manik Surtani
Lead, JBoss Cache
manik(a)jboss.org