Class ScalableRWLock
- All Implemented Interfaces:
Serializable,ReadWriteLock
Scalable Read-Write Lock
A Read-Write Lock that is scalable with the number of threads doing Read. Uses a two-state-machine for the Readers, and averages two synchronized operations.Although this mechanism was independently designed and implemented by the authors, the idea is very similar to the algorithm C-RW-WP described in this paper: NUMA-Aware Reader-Writer locks
Relative to the paper, there are two differences: The threads have no particular order, which means this implementation is not NUMA-aware; Threads attempting a read-lock for the first time are added to a list and removed when the thread terminates, following the mechanism described below. To manage the adding and removal of new Reader threads, we use a ConcurrentLinkedQueue instance named
readersStateList containing all the references to
ReadersEntry (Reader's states), which the Writer scans to determine if the Readers have completed
or not. After a thread terminates, the finalize() of the associated ReaderEntry
instance will be called, which will remove the Reader's state reference from the
readersStateList, to avoid memory leaking. Advantages:
- Implements
java.util.concurrent.locks.ReadWriteLock - When there are very few Writes, the performance scales with the number of Reader threads
- No need to call initialization/cleanup functions per thread
- No limitation on the number of concurrent threads
- Not Reentrant
- Has Writer-Preference
- Memory footprint increases with number of threads by sizeof(ReadersEntry) x O(N_threads)
- Does not support
lockInterruptibly() - Does not support
newCondition()
sharedLock() is two synchronized
calls: an AtomicInteger.set() on a cache line that is held in exclusive mode by the core
where the current thread is running, and an AtomicLong.get() on a shared cache line.This means that when doing several sequential calls of sharedLock()/unlock() on the same instance, the performance penalty will be small because the accessed variables will most likely be in L1/L2 cache.
- Author:
- Pedro Ramalhete, Andreia Correia
- See Also:
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoidAcquires the write lock.booleanAcquires the write lock only if it is not held by another thread at the time of invocation.booleanexclusiveTryLockNanos(long nanosTimeout) Acquires the write lock if it is not held by another thread within the given waiting time.voidAttempts to release the write lock.readLock()protected voidremoveState(AtomicInteger state) This function should be called only from ReadersEntry.finalize()voidAcquires the read lock.booleanAcquires the read lock only if the write lock is not held by another thread at the time of invocation.booleansharedTryLockNanos(long nanosTimeout) Acquires the read lock if the write lock is not held by another thread within the given waiting time.voidAttempts to release the read lock.
-
Constructor Details
-
ScalableRWLock
public ScalableRWLock()Default constructor
-
-
Method Details
-
readLock
- Specified by:
readLockin interfaceReadWriteLock
-
writeLock
- Specified by:
writeLockin interfaceReadWriteLock
-
removeState
This function should be called only from ReadersEntry.finalize()- Parameters:
state- The reader's state that we wish to remove from the ConcurrentLinkedQueue
-
exclusiveLock
public void exclusiveLock()Acquires the write lock.Acquires the write lock if neither the read nor write lock are held by another thread and returns immediately, setting the write lock
reentrantWriterCountto one.If the current thread already holds the write lock then the
reentrantWriterCountis incremented by one and the method returns immediately.If the lock is held by another thread, then the current thread yields and lies dormant until the write lock has been acquired, at which time the
reentrantWriterCountis set to one. -
exclusiveUnlock
public void exclusiveUnlock()Attempts to release the write lock.If the current thread is the holder of this lock then the
reentrantWriterCountis decremented. IfreentrantWriterCountis now zero then the lock is released. If the current thread is not the holder of this lock thenIllegalMonitorStateExceptionis thrown.- Throws:
IllegalMonitorStateException- if the current thread does not hold this lock.
-
exclusiveTryLock
public boolean exclusiveTryLock()Acquires the write lock only if it is not held by another thread at the time of invocation.Acquires the write lock if the write lock is not held by another thread and returns immediately with the value
trueif and only if no other thread is attempting a read lock, setting the write lockwriterLoopcount to one.If the current thread already holds this lock then the
reentrantWriterCountcount is incremented by one and the method returnstrue.If the write lock is held by another thread then this method will return immediately with the value
false.- Returns:
trueif the write lock was free and was acquired by the current thread, or the write lock was already held by the current thread; andfalseotherwise.
-
exclusiveTryLockNanos
Acquires the write lock if it is not held by another thread within the given waiting time.Acquires the write lock if the write lock is not held by another thread and returns immediately with the value
trueif and only if no other thread is attempting a read lock, setting the write lockreentrantWriterCountto one. If another thread is attempting a read lock, this function may yield until the read lock is released.If the current thread already holds this lock then the
reentrantWriterCountis incremented by one and the method returnstrue.If the write lock is held by another thread then the current thread yields and lies dormant until one of two things happens:
- The write lock is acquired by the current thread; or
- The specified waiting time elapses
If the write lock is acquired then the value
trueis returned and the write lockreentrantWriterCountis set to one.- Parameters:
nanosTimeout- the time to wait for the write lock in nanoseconds- Returns:
trueif the lock was free and was acquired by the current thread, or the write lock was already held by the current thread; andfalseif the waiting time elapsed before the lock could be acquired.- Throws:
InterruptedException
-