Stamped Locks - Java 8

Multi-threaded code has long been the bane of server developers (just ask Oracle Java Language Architect and concurrency guru Brian Goetz). Over time complex idioms were added to the core Java libraries to help minimize thread waits when accessing shared resources. One of these is the classic ReadWriteLock that lets you divide code into sections that need to be mutually exclusive (writers), and sections that don’t (readers).

StampedLock has an "optimistic" mode that issues a stamp that is returned by each locking operation to serve as a sort of admission ticket; each unlock operation needs to be passed its correlating stamp. Any thread that happens to acquire a write lock while a reader was holding an optimistic lock, will cause the optimistic unlock to be invalidated (the stamp is no longer valid). At that point the application can start all over, perhaps with a pessimistic lock (also implemented in StampedLock.) Managing that is up to you, and one stamp cannot be used to unlock another – so be super careful.On paper this sounds great. The problem is that the ReadWriteLock can be super slow (up to 10x), which kind of defeats its purpose. Java 8 introduces a new ReadWrite lock – called StampedLock. The good news here is that this guy is seriously fast. The bad news is that it’s more complicated to use and lugs around more state. It’s also not reentrant, which means a thread can have the dubious pleasure of deadlocking against itself.
Let’s see this lock in action-
long stamp = lock.tryOptimisticRead(); // non blocking path - super fast
work(); // we're hoping no writing will go on in the meanwhile
if (lock.validate(stamp)){
       //success! no contention with a writer thread 
}
else {
       //another thread must have acquired a write lock in the meanwhile, changing the stamp. 
       //bummer - let's downgrade to a heavier read lock

            stamp = lock.readLock(); //this is a traditional blocking read lock 
       try {
                 //no writing happening now
                 work();

       }
       finally {
            lock.unlock(stamp); // release using the correlating stamp
       }
}

Comments

Popular posts from this blog

WMI Static Port configuration

Optimizing your JVM for Best Performance

How do I disable FOREIGN KEY checking for the time of database schema migration?