public class StampedLock extends Object implements Serializable
writeLock()
メソッドは、排他的アクセスを待機してブロックする可能性があり、ロックを解放するためにunlockWrite(long)
メソッドで使用できるスタンプを返します。時間指定のないバージョンと時間指定のあるバージョンのtryWriteLock
も用意されています。ロックが書込みモードで保持されているときは、読取りロックを取得することはできず、オプティミスティック読取り検証はすべて失敗します。 readLock()
メソッドは、非排他的アクセスを待機してブロックする可能性があり、ロックを解放するためにunlockRead(long)
メソッドで使用できるスタンプを返します。時間指定のないバージョンと時間指定のあるバージョンのtryReadLock
も用意されています。 tryOptimisticRead()
メソッドは、現在ロックが書込みモードで保持されていない場合のみ、ゼロ以外のスタンプを返します。validate(long)
メソッドは、指定されたスタンプの取得以降にロックが書込みモードで取得されていない場合、trueを返します。このモードは、ライターがいつでも破ることのできる、きわめて弱い読取りロックと見なすことができます。読取り専用の短いコード・セグメントにオプティミスティック・モードを使用すると、競合が減り、スループットが向上ことがよくあります。ただし、その使用は本質的に脆弱です。オプティミスティック読取りセクションでは、フィールドを読み取り、それらを後で検証してから使用するためにローカル変数に保持することだけを行うべきです。オプティミスティック・モードでは、読み取られたフィールドが大きく矛盾している可能性があるため、一貫性をチェックしたりvalidate()
メソッドを繰り返し呼び出したりするためのデータ表現に十分習熟している場合にかぎり使用できます。たとえば、最初にオブジェクト参照または配列参照を読み取り、次にそのフィールド、要素、またはメソッドの1つにアクセスする場合、通常そのような手順が必要になります。 このクラスは、条件に応じて3つのモード間の変換を提供するメソッドもサポートしています。たとえば、tryConvertToWriteLock(long)
メソッドはモードの「アップグレード」を試み、(1)すでに書込みモードの場合、(2)読取りモードで他にリーダーがない場合、または(3)オプティミスティック・モードでロックが使用可能な場合は、有効な書込みスタンプを返します。これらのメソッドの形式は、再試行ベースの設計で発生するコードの膨張をいくから軽減できるように設計されています。
StampedLockは、スレッドセーフなコンポーネントの開発で内部ユーティリティとして使用するために設計されています。これらを使用するには、保護するデータ、オブジェクト、およびメソッドの内部プロパティの知識が必要です。これらは再入可能ではないため、ロックされている本体では、ロックの再取得を試みる可能性のある他の不明なメソッドを呼び出すべきではありません(ただし、スタンプを使用または変換できる他のメソッドにスタンプを渡すことはできます)。読取りロック・モードを使用するには、関連するコード・セクションが副作用を持っていないことが必要です。未検証のオプティミスティック読取りセクションでは、潜在的な不整合を許容できることがわかっていないメソッドを呼び出すことはできません。スタンプは有限表示を使用し、暗号的にセキュアではありません(つまり、有効なスタンプが推測可能な場合があります)。スタンプの値は、1年以上の連続動作の後で再循環する場合があります。これより長い期間、使用も検証もされずに保持されたスタンプは、正しく検証できない場合があります。StampedLockは直列化可能ですが、常に初期のロック解除された状態に直列化復元されるため、リモート・ロックには役立ちません。
StampedLockのスケジューリング・ポリシーでは、リーダーとライターのどちらを優先するかに一貫性がありません。「try」メソッドはすべてベスト・エフォート型であり、スケジューリング・ポリシーや公平性ポリシーに必ずしも準拠していません。ロックを取得または変換する「try」メソッドからゼロが返された場合、ロックの状態に関する情報は提供されません。それ以降の呼び出しが成功する場合もあります。
このクラスでは、複数のロック・モードを調整する使用方法がサポートされているため、Lock
インタフェースやReadWriteLock
インタフェースは直接実装されません。ただし、関連する機能セットだけを必要とするアプリケーションでは、StampedLockがasReadLock()
、asWriteLock()
、またはasReadWriteLock()
と見なされることもあります。
使用例。単純な2次元の点を保持するクラスにおけるいくつかの使用方法を次に示します。サンプル・コードにはいくつかのtry/catch技法が示されていますが、その本体で例外が発生する可能性はないため、ここではこれらが厳密に必要なわけではありません。
class Point {
private double x, y;
private final StampedLock sl = new StampedLock();
void move(double deltaX, double deltaY) { // an exclusively locked method
long stamp = sl.writeLock();
try {
x += deltaX;
y += deltaY;
} finally {
sl.unlockWrite(stamp);
}
}
double distanceFromOrigin() { // A read-only method
long stamp = sl.tryOptimisticRead();
double currentX = x, currentY = y;
if (!sl.validate(stamp)) {
stamp = sl.readLock();
try {
currentX = x;
currentY = y;
} finally {
sl.unlockRead(stamp);
}
}
return Math.sqrt(currentX * currentX + currentY * currentY);
}
void moveIfAtOrigin(double newX, double newY) { // upgrade
// Could instead start with optimistic, not read mode
long stamp = sl.readLock();
try {
while (x == 0.0 && y == 0.0) {
long ws = sl.tryConvertToWriteLock(stamp);
if (ws != 0L) {
stamp = ws;
x = newX;
y = newY;
break;
}
else {
sl.unlockRead(stamp);
stamp = sl.writeLock();
}
}
} finally {
sl.unlock(stamp);
}
}
}
コンストラクタと説明 |
---|
StampedLock()
新しいロックを、最初はロック解除された状態で作成します。
|
修飾子と型 | メソッドと説明 |
---|---|
Lock |
asReadLock()
|
ReadWriteLock |
asReadWriteLock()
このStampedLockの
ReadWriteLock ビューを返します。そこでは、ReadWriteLock.readLock() メソッドがasReadLock() にマップされ、ReadWriteLock.writeLock() がasWriteLock() にマップされます。 |
Lock |
asWriteLock()
|
int |
getReadLockCount()
このロック用に保持されている読込みロックの数を照会します。
|
boolean |
isReadLocked()
現在ロックが非排他的に保持されている場合は
true を返します。 |
boolean |
isWriteLocked()
現在ロックが排他的に保持されている場合は
true を返します。 |
long |
readLock()
ロックを非排他的に取得し、利用可能になるまで必要に応じてブロックします。
|
long |
readLockInterruptibly()
ロックを非排他的に取得し、利用可能になるまで、または現在のスレッドが割り込まれるまで、必要に応じてブロックします。
|
String |
toString()
このロックおよびその状態を識別する文字列を返します。
|
long |
tryConvertToOptimisticRead(long stamp)
ロック状態が指定されたスタンプと一致する場合、そのスタンプがロックの保持を表していれば、それを解除し、監視スタンプを返します。
|
long |
tryConvertToReadLock(long stamp)
ロック状態が指定されたスタンプと一致する場合に、次のいずれかのアクションを実行します。
|
long |
tryConvertToWriteLock(long stamp)
ロック状態が指定されたスタンプと一致する場合に、次のいずれかのアクションを実行します。
|
long |
tryOptimisticRead()
後で検証できるスタンプを返します。排他的にロックされている場合はゼロを返します。
|
long |
tryReadLock()
ロックがすぐに利用できる場合に、それを非排他的に取得します。
|
long |
tryReadLock(long time, TimeUnit unit)
指定された時間内でロックが利用可能になり、現在のスレッドで割込みが発生していない場合に、それを非排他的に取得します。
|
boolean |
tryUnlockRead()
読取りロックが保持される場合に、スタンプ値を必要としないで、その保持を解除します。
|
boolean |
tryUnlockWrite()
書込みロックが保持される場合に、スタンプ値を必要としないで、それを解除します。
|
long |
tryWriteLock()
ロックがすぐに利用できる場合に、それを排他的に取得します。
|
long |
tryWriteLock(long time, TimeUnit unit)
指定された時間内でロックが利用可能になり、現在のスレッドで割込みが発生していない場合に、それを排他的に取得します。
|
void |
unlock(long stamp)
ロック状態が指定されたスタンプと一致する場合に、対応するロック・モードを解除します。
|
void |
unlockRead(long stamp)
ロック状態が指定されたスタンプと一致する場合に、非排他ロックを解除します。
|
void |
unlockWrite(long stamp)
ロック状態が指定されたスタンプと一致する場合に、排他ロックを解除します。
|
boolean |
validate(long stamp)
指定されたスタンプの発行以降にロックが排他的に取得されなかった場合にtrueを返します。
|
long |
writeLock()
ロックを排他的に取得し、必要に応じて利用可能になるまでブロックします。
|
long |
writeLockInterruptibly()
ロックを排他的に取得し、必要に応じて利用可能になるか、現在のスレッドで割込みが発生するまでブロックします。
|
public long writeLock()
public long tryWriteLock()
public long tryWriteLock(long time, TimeUnit unit) throws InterruptedException
Lock.tryLock(long,TimeUnit)
メソッドに指定されているものと同じです。time
- ロックの最長待機時間unit
- time
引数の時間単位InterruptedException
- ロックを取得する前に現在のスレッドで割込みが発生した場合public long writeLockInterruptibly() throws InterruptedException
Lock.lockInterruptibly()
メソッドに指定されているものと同じです。InterruptedException
- ロックを取得する前に現在のスレッドで割込みが発生した場合public long readLock()
public long tryReadLock()
public long tryReadLock(long time, TimeUnit unit) throws InterruptedException
Lock.tryLock(long,TimeUnit)
メソッドに指定されているものと同じです。time
- ロックの最長待機時間unit
- time
引数の時間単位InterruptedException
- ロックを取得する前に現在のスレッドで割込みが発生した場合public long readLockInterruptibly() throws InterruptedException
Lock.lockInterruptibly()
メソッドに指定されているものと同じです。InterruptedException
- ロックを取得する前に現在のスレッドで割込みが発生した場合public long tryOptimisticRead()
public boolean validate(long stamp)
tryOptimisticRead()
またはこのロックのロック・メソッドから取得されたものではない値を指定してこのメソッドを呼び出した場合、その効果や結果は定義されていません。stamp
- スタンプtrue
、それ以外の場合はfalsepublic void unlockWrite(long stamp)
stamp
- 書込みロック操作によって返されたスタンプIllegalMonitorStateException
- スタンプがこのロックの現在の状態と一致しない場合public void unlockRead(long stamp)
stamp
- 読取りロック操作によって返されたスタンプIllegalMonitorStateException
- スタンプがこのロックの現在の状態と一致しない場合public void unlock(long stamp)
stamp
- ロック操作によって返されたスタンプIllegalMonitorStateException
- スタンプがこのロックの現在の状態と一致しない場合public long tryConvertToWriteLock(long stamp)
stamp
- スタンプpublic long tryConvertToReadLock(long stamp)
stamp
- スタンプpublic long tryConvertToOptimisticRead(long stamp)
stamp
- スタンプpublic boolean tryUnlockWrite()
true
。それ以外の場合はfalsepublic boolean tryUnlockRead()
true
。それ以外の場合はfalsepublic boolean isWriteLocked()
true
を返します。true
public boolean isReadLocked()
true
を返します。true
public int getReadLockCount()
public String toString()
"Unlocked"
または文字列"Write-locked"
または文字列"Read-locks:"
に続いて、現在保持されている読取りロックの数が含まれます。public Lock asReadLock()
Lock
ビューを返します。そこでは、Lock.lock()
メソッドがreadLock()
にマップされ、他のメソッドも同様にマップされます。返されたLockはCondition
をサポートしていないため、Lock.newCondition()
メソッドはUnsupportedOperationException
をスローします。public Lock asWriteLock()
Lock
ビューを返します。そこでは、Lock.lock()
メソッドがwriteLock()
にマップされ、他のメソッドも同様にマップされます。返されたLockはCondition
をサポートしていないため、Lock.newCondition()
メソッドはUnsupportedOperationException
をスローします。public ReadWriteLock asReadWriteLock()
ReadWriteLock
ビューを返します。そこでは、ReadWriteLock.readLock()
メソッドがasReadLock()
にマップされ、ReadWriteLock.writeLock()
がasWriteLock()
にマップされます。 バグまたは機能を送信
詳細なAPIリファレンスおよび開発者ドキュメントについては、Java SEのドキュメントを参照してください。そのドキュメントには、概念的な概要、用語の定義、回避方法、有効なコード例などの、開発者を対象にしたより詳細な説明が含まれています。
Copyright© 1993, 2014, Oracle and/or its affiliates. All rights reserved.