by Uwe B. Meding
Developing multi-threaded code has always been a non-trivial undertaking. The ReadWriteLock
is the typical mechanism used to help minimize thread waits when accessing shared resources. It lets you separate the code into sections that need to be mutually exclusive (writers), and sections that don’t (readers).
The issue with ReadWriteLock
is that it can be very slow (up to 10x), which kind of defeats its purpose. Java 8 introduces a new read/write lock – called StampedLock
. It has a number of methods that support extremely fast locking. One of the drawbacks of stamped locks is that they re not as straightforward to use as the heavy traditional lock. It’s also not re-entrant, which means a thread can deadlock against itself.
StampedLock has an “optimistic” mode that issues a handle (“stamp”) that is returned by each locking operation; each unlock operation releases its correlating stamp. Any thread that acquires 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). The application can then retry the same operation, or attempt a heavier lock. For example, here is a snippet of an application that attempts to use a fast lock first, and if the operation fails, attempts to use a heavy read lock.
StampedLock lock = new StampedLock(); // try the fast (non-blocking) lock first long stamp = 0L; try { stamp = lock.tryOptimisticRead(); doSomeWork(); if (lock.validate(stamp)) { // Great! no contention, the work was successful } else { // another thread acquired a write lock while we were doing some work, // repeat the operation using the heavy (blocking) lock stamp = lock.readLock(); doSomeWork(); } } finally { // release the lock stamp if (stamp != 0L) { lock.unlock(stamp); } }
Leave a Reply
You must be logged in to post a comment.