public final class ReadWriteLock
extends java.lang.Object
ReadWriteLock
class is an implementation of a reentrant
multiple-reader/single-writer lock. It reference counts by thread to ensure
that read locks or write locks can be acquired multiple times by a thread,
but that every acquisition by a given thread is balanced by a corresponding
release.
An unusual feature of this class is support for WriteLockRequestListener
s. A background thread that must hold a read lock
to do its work, but which does not wish to block a foreground thread
attempting to write (e.g., the event thread processing a key type event),
can add itself as a write lock request listener and cancel itself if the
event fires. The background thread can add the listener only after the read
lock is acquired, and must remove the listener before releasing the read
lock. Note that only a non-interruptible write triggers the event.
The basis of the implementation has recently converted from thread wait and
notify to ReentrantReadWriteLock
. The
original implementation was refactored behind a newly introduced
ReadWriteLockImplementation
interface, as LegacyReadWriteLockImplementation
}, and a new JdkReadWriteLockImplementation
was introduced and is now the default.
Upgrading a lock, that is, acquiring a write lock while holding a read lock
on the same thread, has historically been supported by this class. However,
two threads trying to upgrade can deadlock. The legacy implementation logs a
message with level Severe when a lock is upgraded; the JDK implementation
throws IllegalMonitorStateException
.
The legacy implementation, to help diagnose deadlocks, logged a warning with substantial thread detail whenever a thread was blocked waiting for a lock for 20 seconds. An operation which was very slow while holding a lock, but not actually deadlocked, would cause a false positive. The JDK implementation uses the same trigger, but then invokes the deadlock detection service provided by the JDK to eliminate the false positives.
Modifier and Type | Class and Description |
---|---|
static class |
ReadWriteLock.Implementation
An enumeration of the implementation types for a ReadWriteLock.
|
static class |
ReadWriteLock.Options
An enumeration of the configuration options for a ReadWriteLock.
|
Modifier and Type | Field and Description |
---|---|
static int |
DEFAULT_DEADLOCK_INTERVAL |
static int |
DEFAULT_HISTORY_LIMIT |
static ReadWriteLock.Implementation |
DEFAULT_IMPLEMENTATION |
static java.util.EnumSet<ReadWriteLock.Options> |
DEFAULT_OPTIONS |
static int |
DEFAULT_WAIT_INTERVAL |
Constructor and Description |
---|
ReadWriteLock()
Creates an anonymous lock.
|
ReadWriteLock(java.lang.String name)
Creates a named lock.
|
Modifier and Type | Method and Description |
---|---|
boolean |
addWriteLockRequestListener(WriteLockRequestListener listener)
Adds a
WriteLockRequestListener on behalf of the current thread. |
void |
appendSnapshot(java.lang.StringBuilder buffer) |
java.lang.String |
getName()
Gets the name of this lock.
|
int |
getReadHoldCount()
Gets the number of times the current thread has taken the read lock for
this lock.
|
int |
getWriteHoldCount()
Gets the number of times the current thread has taken the write lock for
this lock.
|
boolean |
isLockHeld()
Gets whether the current thread is holding either a read or write
lock for this lock.
|
boolean |
isReadLockHeld()
Gets whether the current thread is holding a read lock for this lock.
|
boolean |
isWriteLockHeld()
Gets whether the current thread is holding a write lock for this
lock.
|
void |
readLock()
Acquires a read lock for the current thread, blocking until available.
|
void |
readLockInterruptibly()
Acquires a read lock for the current thread, blocking until available.
|
void |
readUnlock()
Releases a read lock for the current thread.
|
void |
removeWriteLockRequestListener(WriteLockRequestListener listener)
Removes a
WriteLockRequestListener on behalf of the current
thread. |
void |
setEventLog(Log log) |
void |
setName(java.lang.String name)
Sets the name of this lock.
|
java.lang.String |
toString() |
boolean |
tryReadLock()
Acquires a read lock for the current thread only if possible without
blocking the thread; returns without acquiring it otherwise.
|
boolean |
tryWriteLock()
Acquires the write lock for the current thread only if possible without
blocking the thread; returns without acquiring it otherwise.
|
void |
writeLock()
Acquires the write lock for the current thread, blocking until available.
|
void |
writeLockFromReadLock()
Acquires the write lock for the current thread, upgrading from a read lock
if necessary, blocking until available.
|
void |
writeLockInterruptibly()
Acquires the write lock for the current thread, blocking until available.
|
void |
writeUnlock()
Releases the write lock for the current thread.
|
public static final java.util.EnumSet<ReadWriteLock.Options> DEFAULT_OPTIONS
public static final ReadWriteLock.Implementation DEFAULT_IMPLEMENTATION
public static final int DEFAULT_DEADLOCK_INTERVAL
public static final int DEFAULT_WAIT_INTERVAL
public static final int DEFAULT_HISTORY_LIMIT
public ReadWriteLock()
public ReadWriteLock(java.lang.String name)
public final void setName(java.lang.String name)
public final java.lang.String getName()
public void readLock()
public void readLockInterruptibly() throws java.lang.InterruptedException
java.lang.InterruptedException
- if the current thread is in or gets put in
the interrupted state. The interrupted state
is cleared when this exception is thrown.public boolean tryReadLock()
public void readUnlock()
java.lang.IllegalMonitorStateException
- if the current thread does not hold a
read lock.public boolean addWriteLockRequestListener(WriteLockRequestListener listener)
WriteLockRequestListener
on behalf of the current thread.
The listener will be notified if a thread requests a write lock.java.lang.IllegalMonitorStateException
- if the current thread does not hold a
read lock or if holds a write lock.public void removeWriteLockRequestListener(WriteLockRequestListener listener)
WriteLockRequestListener
on behalf of the current
thread.java.lang.IllegalMonitorStateException
- if the current thread does not hold a
read lock or holds a write lock.public void writeLock()
WriteLockRequestListener
s that the write lock has been
requested.public void writeLockInterruptibly() throws java.lang.InterruptedException
java.lang.InterruptedException
- if the current thread is in or gets put in
the interrupted state. The interrupted state
is cleared when this exception is thrown.public boolean tryWriteLock()
public void writeUnlock()
java.lang.IllegalMonitorStateException
- if the current thread does not hold
the write lock.public void writeLockFromReadLock()
Because there is a point at which the current thread holds no locks, another thread will have the opportunity to acquire a lock and run. Any required preconditions that were checked under the read lock before the upgrade must be rechecked after the upgrade.
public boolean isReadLockHeld()
isLockHeld()
to get whether the current thread
is holding either a read or a write lock for this lock.public boolean isWriteLockHeld()
public boolean isLockHeld()
public int getReadHoldCount()
public int getWriteHoldCount()
public void appendSnapshot(java.lang.StringBuilder buffer)
public void setEventLog(Log log)
public java.lang.String toString()
toString
in class java.lang.Object