- java.lang.Object
-
- java.util.concurrent.locks.ReentrantReadWriteLock
-
- すべての実装されたインタフェース:
Serializable
,ReadWriteLock
public class ReentrantReadWriteLock extends Object implements ReadWriteLock, Serializable
ReentrantLock
と同様のセマンティックスをサポートするReadWriteLock
の実装です。このクラスには次の特性があります。
- 取得順序
このクラスは、ロック・アクセスに対するリーダーまたはライターの優先順序を規定しません。 ただし、オプションの公平性ポリシーをサポートします。
- 不公平モード(デフォルト)
- 不公平として構築された場合は(デフォルト)、読み込みおよび書込みロックに入る順序は指定されず、再入可能性制約に従います。 継続的に競合していた不公平ロックでは、1つ以上のリーダーまたはライター・スレッドを無期限に延期することがありますが、通常は公平ロックよりスループットが高くなります。
- 公平モード
- 公平として構築された場合、スレッドは近似の到着順ポリシーを使用してエントリで競合します。 現在保持されているロックが解放されると、待機時間のもっとも長い単一のライター・スレッドに書込みロックが割り当てられるか、待機中のどのライター・スレッドよりも長く待機しているリーダー・スレッドのグループが存在する場合は、そのグループに読込みロックが割り当てられます。
書込みロックが保持されている場合や待機中のライター・スレッドが存在する場合、公平読込みロック(再入不可能)を取得しようとするスレッドはブロックされます。 そのようなスレッドは、現在待機中のライター・スレッドのうちもっとも古いスレッドが書込みロックを取得して解放するまで、読込みロックを取得しません。 もちろん、待機中のライターが待機を中止し、キュー内でもっとも長く待機している1つ以上のリーダー・スレッドに書込みロックがかかっていない場合は、それらのリーダーに読込みロックが割り当てられます。
読込みロックも書込みロックもかかっていない(つまり待機中のスレッドがない)場合を除き、公平書込みロック(再入不可能)を取得しようとするスレッドはブロックされます。 (非ブロックの
ReentrantReadWriteLock.ReadLock.tryLock()
メソッドとReentrantReadWriteLock.WriteLock.tryLock()
メソッドはこの公平設定に従わず、待機中のスレッドには関係なく、可能であればロックをただちに取得することに注意してください。)
- 再入可能性
このロックにより、リーダーとライターの両方が、
ReentrantLock
のスタイルで読み取りまたは書込みロックを再取得できるようになります。 書き込むスレッドの保持する書込みロックがすべて解放されるまで、再入不可能なリーダーは許可されません。また、ライターは読込みロックを取得できますが、リーダーが書込みロックを取得することはできません。 ほかのアプリケーションの間では、読込みロック下で読込みを実行するメソッドへの呼び出しまたはコールバック中に書込みロックが保持される場合、再入可能性は有用です。 リーダーが書込みロックを取得しようとしても、成功しません。
- ロックの降格
再入可能性を利用すると、書込みロックを取得してから読込みロックを取得し、その後書込みロックを解放するという方法で、書込みロックから読込みロックへの降格が可能になります。 ただし、読込みロックから書込みロックへの昇格はできません。
- ロック取得の割り込み
読込みロックと書込みロックの両方が、ロック取得中の割込みをサポートします。
Condition
のサポート書込みロックの提供する
Condition
実装は、書込みロックに関して、ReentrantLock.newCondition()
によって提供されるCondition
実装がReentrantLock
に対して実行するのと同じように動作します。 このCondition
は当然、書込みロックでのみ使用できます。読込みロックは
Condition
をサポートしていないため、readLock().newCondition()
がUnsupportedOperationException
をスローします。- インストゥルメンテーション
このクラスは、ロックが保持されるか競合するかを判別するメソッドをサポートします。 これらのメソッドは、同期の制御用としてではなく、システム状態の監視用として設計されています。
このクラスの直列化は、組込みロックと同様に動作します。直列化解除されたロックは、直列化時の状態にかかわらず、ロック解除状態になります。
使用例。 次のコード例では、キャッシュを更新したあとにロックの降格を実行する方法を示します(入れ子を使用しない方法で複数のロックを処理する場合の例外処理は特に注意が必要)。
class CachedData { Object data; boolean cacheValid; final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); void processCachedData() { rwl.readLock().lock(); if (!cacheValid) { // Must release read lock before acquiring write lock rwl.readLock().unlock(); rwl.writeLock().lock(); try { // Recheck state because another thread might have // acquired write lock and changed state before we did. if (!cacheValid) { data = ... cacheValid = true; } // Downgrade by acquiring read lock before releasing write lock rwl.readLock().lock(); } finally { rwl.writeLock().unlock(); // Unlock write, still hold read } } try { use(data); } finally { rwl.readLock().unlock(); } } }
class RWDictionary { private final Map<String, Data> m = new TreeMap<>(); private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); private final Lock r = rwl.readLock(); private final Lock w = rwl.writeLock(); public Data get(String key) { r.lock(); try { return m.get(key); } finally { r.unlock(); } } public List<String> allKeys() { r.lock(); try { return new ArrayList<>(m.keySet()); } finally { r.unlock(); } } public Data put(String key, Data value) { w.lock(); try { return m.put(key, value); } finally { w.unlock(); } } public void clear() { w.lock(); try { m.clear(); } finally { w.unlock(); } } }
実装上の注意:
このロックは、最大65535の再帰的書込みロックおよび65535の読込みロックをサポートします。 これらの制限を超えようとすると、ロックしているメソッドから
Error
がスローされます。- 導入されたバージョン:
- 1.5
- 関連項目:
- 直列化された形式
-
-
ネストされたクラスのサマリー
ネストされたクラス 修飾子と型 クラス 説明 static class
ReentrantReadWriteLock.ReadLock
ロックはメソッドReadWriteLock.readLock()
によって返されます。static class
ReentrantReadWriteLock.WriteLock
ロックはメソッドReadWriteLock.writeLock()
によって返されます。
-
コンストラクタのサマリー
コンストラクタ コンストラクタ 説明 ReentrantReadWriteLock()
デフォルト(不公平)の順序プロパティで、新規ReentrantReadWriteLock
を作成します。ReentrantReadWriteLock(boolean fair)
指定された公平性ポリシーを使用して、新しいReentrantReadWriteLock
を作成します。
-
メソッドのサマリー
すべてのメソッド インスタンス・メソッド 具象メソッド 修飾子と型 メソッド 説明 protected Thread
getOwner()
現在書込みロックを所有しているスレッドを返します。ロックが所有されていない場合はnull
を返します。protected Collection<Thread>
getQueuedReaderThreads()
読込みロックの取得を待機中のスレッドを含むコレクションを返します。protected Collection<Thread>
getQueuedThreads()
読込みロックまたは書込みロックのいずれかの取得を待機中のスレッドを含むコレクションを返します。protected Collection<Thread>
getQueuedWriterThreads()
書込みロックの取得を待機中のスレッドを含むコレクションを返します。int
getQueueLength()
読込みロックまたは書込みロックの取得を待機中のスレッドの推定数を返します。int
getReadHoldCount()
現在のスレッドによる、このロック上の再入可能な読込み保持数を照会します。int
getReadLockCount()
このロック用に保持されている読込みロックの数を照会します。protected Collection<Thread>
getWaitingThreads(Condition condition)
書込みロックに関連付けられた指定の状態を待機中のスレッドを含むコレクションを返します。int
getWaitQueueLength(Condition condition)
書込みロックに関連付けられた指定の状態で待機中のスレッドの推定数を返します。int
getWriteHoldCount()
現在のスレッドによる、このロック上の再入可能な書込み保持数を照会します。boolean
hasQueuedThread(Thread thread)
読込みロックまたは書込みロックの取得を待機中の指定のスレッドが存在するかどうかを照会します。boolean
hasQueuedThreads()
読込みロックまたは書込みロックの取得を待機中のスレッドが存在するかどうかを照会します。boolean
hasWaiters(Condition condition)
この書込みロックに関連付けられた指定状態で待機しているスレッドが存在するかどうかを照会します。boolean
isFair()
このロックで公平性がtrueに設定されている場合はtrue
を返します。boolean
isWriteLocked()
書込みロックがスレッドに保持されているかどうかを照会します。boolean
isWriteLockedByCurrentThread()
現在のスレッドがこの書込みロックを保持しているどうかを照会します。String
toString()
このロックおよびその状態を識別する文字列を返します。-
クラス java.lang.Objectで宣言されたメソッド
clone、equals、finalize、getClass、hashCode、notify、notifyAll、wait、wait、wait
-
インタフェース java.util.concurrent.locks.ReadWriteLockで宣言されたメソッド
readLock, writeLock
-
-
-
-
メソッドの詳細
-
isFair
public final boolean isFair()
このロックで公平性がtrueに設定されている場合はtrue
を返します。- 戻り値:
- このロックで公平性がtrueに設定されている場合は
true
-
getOwner
protected Thread getOwner()
現在書込みロックを所有しているスレッドを返します。ロックが所有されていない場合はnull
を返します。 このメソッドが所有者ではないスレッドによって呼び出される場合、戻り値には現在のロック状態の最大限の近似値が反映されます。 たとえば、ロックの取得を試みていてまだ取得していないスレッドが存在する場合も、所有者は一時的にnull
になる場合があります。 このメソッドは、より包括的なロック監視機能を提供するサブクラスの構築を容易にする目的で設計されています。- 戻り値:
- 所有者。所有されていない場合は
null
-
getReadLockCount
public int getReadLockCount()
このロック用に保持されている読込みロックの数を照会します。 このメソッドは、同期の制御用としてではなく、システム状態の監視用として設計されています。- 戻り値:
- 保持する読込みロックの数
-
isWriteLocked
public boolean isWriteLocked()
書込みロックがスレッドに保持されているかどうかを照会します。 このメソッドは、同期の制御用としてではなく、システム状態の監視用として設計されています。- 戻り値:
- いずれかのスレッドが書込みロックを保持している場合は
true
。それ以外の場合はfalse
-
isWriteLockedByCurrentThread
public boolean isWriteLockedByCurrentThread()
現在のスレッドがこの書込みロックを保持しているどうかを照会します。- 戻り値:
- 現在のスレッドが書込みロックを保持している場合は
true
。それ以外の場合はfalse
-
getWriteHoldCount
public int getWriteHoldCount()
現在のスレッドによる、このロック上の再入可能な書込み保持数を照会します。 ライター・スレッドは、ロック解除アクションと一致しない各ロック・アクション用のロックを保持します。- 戻り値:
- 現在のスレッドの、書込みロックに対する保持数。現在のスレッドがこのロックを保持していない場合はゼロ
-
getReadHoldCount
public int getReadHoldCount()
現在のスレッドによる、このロック上の再入可能な読込み保持数を照会します。 読込みスレッドには、ロック解除アクションと一致しないロック・アクションごとに、ロック保持が存在します。- 戻り値:
- 現在のスレッドの、読込みロックに対する保持数。現在のスレッドがこのロックを保持していない場合はゼロ
- 導入されたバージョン:
- 1.6
-
getQueuedWriterThreads
protected Collection<Thread> getQueuedWriterThreads()
書込みロックの取得を待機中のスレッドを含むコレクションを返します。 実際のスレッド・セットは、結果の構築中にも動的に変化する可能性があるため、返されるコレクションは最善の努力を払った上での推定に過ぎません。 返されるコレクションの要素には、特定の順序は存在しません。 このメソッドは、より包括的なロック監視機能を提供するサブクラスの構築を容易にする目的で設計されています。- 戻り値:
- スレッドのコレクション
-
getQueuedReaderThreads
protected Collection<Thread> getQueuedReaderThreads()
読込みロックの取得を待機中のスレッドを含むコレクションを返します。 実際のスレッド・セットは、結果の構築中にも動的に変化する可能性があるため、返されるコレクションは最善の努力を払った上での推定に過ぎません。 返されるコレクションの要素には、特定の順序は存在しません。 このメソッドは、より包括的なロック監視機能を提供するサブクラスの構築を容易にする目的で設計されています。- 戻り値:
- スレッドのコレクション
-
hasQueuedThreads
public final boolean hasQueuedThreads()
読込みロックまたは書込みロックの取得を待機中のスレッドが存在するかどうかを照会します。 取消しはいつでも発生する可能性があるため、true
が返されても、ほかのいずれかのスレッドがロックを取得することは保証されていません。 このメソッドは、主にシステム状態の監視に使用する目的で設計されています。- 戻り値:
- ロックの取得を待機中のほかのスレッドが存在する可能性がある場合は
true
-
hasQueuedThread
public final boolean hasQueuedThread(Thread thread)
読込みロックまたは書込みロックの取得を待機中の指定のスレッドが存在するかどうかを照会します。 取消しはいつでも発生する可能性があるため、true
が返されても、このスレッドがロックを取得することは保証されていません。 このメソッドは、主にシステム状態の監視に使用する目的で設計されています。- パラメータ:
thread
- スレッド- 戻り値:
- 指定されたスレッドがキューに入れられており、このロックを待機中である場合は
true
- 例外:
NullPointerException
- スレッドがnullの場合
-
getQueueLength
public final int getQueueLength()
読込みロックまたは書込みロックの取得を待機中のスレッドの推定数を返します。 このメソッドが内部のデータ構造をトラバースしている間にも、スレッド数が動的に変化する場合があるため、この値は推定に過ぎません。 このメソッドは、同期の制御用としてではなく、システム状態の監視用として設計されています。- 戻り値:
- このロックを待機しているスレッドの推定数
-
getQueuedThreads
protected Collection<Thread> getQueuedThreads()
読込みロックまたは書込みロックのいずれかの取得を待機中のスレッドを含むコレクションを返します。 実際のスレッド・セットは、結果の構築中にも動的に変化する可能性があるため、返されるコレクションは最善の努力を払った上での推定に過ぎません。 返されるコレクションの要素には、特定の順序は存在しません。 このメソッドは、より包括的な監視機能を提供するサブクラスの構築を容易にする目的で設計されています。- 戻り値:
- スレッドのコレクション
-
hasWaiters
public boolean hasWaiters(Condition condition)
この書込みロックに関連付けられた指定状態で待機しているスレッドが存在するかどうかを照会します。 タイム・アウトおよび割込みはいつでも発生する可能性があるため、true
が返されても、将来signal
がスレッドを起動させることは保証されていません。 このメソッドは、主にシステム状態の監視に使用する目的で設計されています。- パラメータ:
condition
- 状態- 戻り値:
- 待機中のスレッドが存在する場合は
true
- 例外:
IllegalMonitorStateException
- このロックを保持していない場合IllegalArgumentException
- 指定された状態がこのロックと関連付けられていない場合NullPointerException
- 状態がnullの場合
-
getWaitQueueLength
public int getWaitQueueLength(Condition condition)
書込みロックに関連付けられた指定の状態で待機中のスレッドの推定数を返します。 タイム・アウトおよび割り込みの発生する可能性はいつでも存在するため、推定数は、実際の待機者数に関する上限を示すに過ぎません。 このメソッドは、同期の制御用としてではなく、システム状態の監視用として設計されています。- パラメータ:
condition
- 状態- 戻り値:
- 待機中のスレッドの推定数
- 例外:
IllegalMonitorStateException
- このロックを保持していない場合IllegalArgumentException
- 指定された状態がこのロックと関連付けられていない場合NullPointerException
- 状態がnullの場合
-
getWaitingThreads
protected Collection<Thread> getWaitingThreads(Condition condition)
書込みロックに関連付けられた指定の状態を待機中のスレッドを含むコレクションを返します。 実際のスレッド・セットは、結果の構築中にも動的に変化する可能性があるため、返されるコレクションは最善の努力を払った上での推定に過ぎません。 返されるコレクションの要素には、特定の順序は存在しません。 このメソッドは、より包括的な状態監視機能を提供するサブクラスの構築を容易にする目的で設計されています。- パラメータ:
condition
- 状態- 戻り値:
- スレッドのコレクション
- 例外:
IllegalMonitorStateException
- このロックを保持していない場合IllegalArgumentException
- 指定された状態がこのロックと関連付けられていない場合NullPointerException
- 状態がnullの場合
-
-