|
JavaTM Platform Standard Ed. 6 |
|||||||||
前のクラス 次のクラス | フレームあり フレームなし | |||||||||
概要: 入れ子 | フィールド | コンストラクタ | メソッド | 詳細: フィールド | コンストラクタ | メソッド |
java.lang.Object java.util.concurrent.locks.AbstractOwnableSynchronizer java.util.concurrent.locks.AbstractQueuedSynchronizer
public abstract class AbstractQueuedSynchronizer
ブロックロック、および先入れ先出し (FIFO) 待機キューに依存する関連シンクロナイザ (セマフォー、イベントなど) を実装するフレームワークを提供します。このクラスは、状態表現を単一の原子 int 値に依存する大半の種類のシンクロナイザの有用な基盤として設計されています。サブクラスは、この状態を変更する protected メソッドを定義する必要があり、そのメソッドは取得または解放中のオブジェクトを使用して状態の意味を定義します。これらが指定されると、このクラス内のほかのメソッドはすべてのキューおよびブロック機構を稼働させます。サブクラスは、ほかの状態フィールドを維持できますが、同期に関する追跡を行えるのは getState()
、setState(int)
、および compareAndSetState(int, int)
メソッドを使用して操作され、原子的に更新された int 値だけです。
サブクラスは、public ではない内部ヘルパークラスとして定義する必要があります。これは、それを囲むクラスの同期プロパティーの実装に使用されます。AbstractQueuedSynchronizer クラスは、同期インタフェースを一切実装しません。その代わり、具象ロックおよび関連するシンクロナイザにより適宜呼び出して public メソッドを実装できる acquireInterruptibly(int)
などのメソッドを定義します。
このクラスは、デフォルトの「排他」モードおよび「共有」モードのいずれかまたは両方をサポートします。排他モードで取得されると、ほかのスレッドが取得を試みても成功しません。共有モードでは、複数のスレッドによる取得が可能です (ただし、必ず取得が成功する必要があるわけではない)。このクラスは、共有モードの取得が成功した場合、待機中の次のスレッド (存在する場合) も取得可能かどうかを判別する必要があるという機構的な意味を除き、これらの違いを「認識」しません。別のモードで待機中のスレッドは、同じ FIFO キューを共有します。通常、実装サブクラスはこれらのモードの 1 つだけをサポートしますが、ReadWriteLock
などでは両方が機能することが可能です。排他モードまたは共有モードのみをサポートするサブクラスは、使用しないモードをサポートするメソッドを定義する必要はありません。
このクラスは、排他モードをサポートするサブクラスにより Condition
実装として使用可能な、入れ子にされた AbstractQueuedSynchronizer.ConditionObject
クラスを定義します。 isHeldExclusively()
は、このクラスに関し、同期が現在のスレッドに関して排他的に保持されるか、現在の getState()
値を使って呼び出された release(int)
メソッドがこのオブジェクトを完全に解放するか、この保存済み状態値が指定されると acquire(int)
が最終的にこのオブジェクトを以前に取得された状態に復元するかをレポートします。それ以外では、AbstractQueuedSynchronizer メソッドはこの状態を作成しないため、この制限を満たすことができない場合は使用しないでください。当然のことですが、AbstractQueuedSynchronizer.ConditionObject
の動作はシンクロナイザ実装のセマンティクスに依存します。
このクラスは、内部キューの検証、計測、および監視用メソッド、および状態オブジェクト用の類似メソッドを提供します。これらは、必要に応じ、同期機構の AbstractQueuedSynchronizer を使用してクラス内にエクスポートできます。
このクラスを直列化すると、基になる原子整数の保守状態だけが格納されるため、直列化復元されたオブジェクトは空のスレッドキューを保持します。直列化機能を必要とする通常のサブクラスは、直列化復元時にこれを既知の初期状態に復元する readObject メソッドを定義します。
このクラスをシンクロナイザの基盤として使用するには、適用可能であれば getState()
、setState(int)
、compareAndSetState(int, int)
を使用して同期状態の検証や変更を行うことにより、次のメソッドを再定義します。
UnsupportedOperationException
をスローします。これらのメソッドの実装は、内部がスレッドセーフでなければならず、また、通常は短くかつブロッキングなしでなければなりません。これらのメソッドの定義は、このクラスのサポートされる唯一の使用方法です。ほかのメソッドはすべて、個別に変更することはできないため、final と宣言されます。
AbstractOwnableSynchronizer
から継承されるメソッドは、排他的なシンクロナイザを所有するスレッドを追跡するときに便利です。ロックを保持するスレッドを判断するのに役立つ監視および診断のツールが有効になるため、これらを使用することをお勧めします。
このクラスは内部の FIFO キューに基づくとはいえ、自動的に FIFO 取得ポリシーが適用されるわけではありません。排他的な同期のコアは、次の形式になります。
Acquire: while (!tryAcquire(arg)) { enqueue thread if it is not already queued; possibly block current thread; } Release: if (tryRelease(arg)) unblock the first queued thread;(共有モードも似ているが、カスケード信号が関係する場合がある)
取得のチェックはキューに入れられる前に呼び出されるので、新たに取得されるスレッドは、ブロックおよびキューに入れられるほかのスレッドより先に「バージする」ことが可能です。ただし、必要であれば、tryAcquire や tryAcquireShared を定義して、1 つ以上の検証メソッドを内部で呼び出すことにより、バージを無効にできます。特に、厳密な FIFO ロックは tryAcquire を定義して、getFirstQueuedThread()
が現在のスレッドを返さない場合にただちに false を返すことが可能です。通常望ましい非厳密で公平なバージョンは、hasQueuedThreads()
が true を返し、getFirstQueuedThread が現在のスレッドでない (つまり getFirstQueuedThread が null でも現在のスレッドでもない) 場合にのみ、ただちに false を返すことができます。さらなるバリエーションが可能です。
通常、スループットとスケーラビリティーは、デフォルトのバージ (「貪欲」、「放棄」、「護送回避」とも呼ばれる) ストラテジの最上位に位置します。これが偏りがなく、枯渇しないことは保証されませんが、先にキューに入れられたスレッドは、あとでキューに入れられるスレッドより前に再競合が許可され、各再競合は着信するスレッドに対して成功する公平な機会を保持します。また、取得は、通常の意味では「スピン」しませんが、ブロッキング前にほかの計算に挿入された tryAcquire の複数の呼び出しを実行可能です。これにより、排他的な同期が短期的に保持されるだけの場合、スピンの恩恵の多くを享受できます。 さらに、排他的な同期が保持されない場合にはほとんど負担なしで、その恩恵を享受できます。 必要に応じ、「近道」チェックを持つメソッドを取得する呼び出しを前に配置することで、この値を増やすことができます。
これは、シンクロナイザが競合する可能性が少ない場合、hasContended()
や hasQueuedThreads()
を事前にチェックするなどの方法で実行できます。このクラスは、使用範囲を int 状態、パラメータの取得と解放、および内部 FIFO 待機キューに依存可能なシンクロナイザに限定することにより、効率的で拡張性の高い同期基盤の一部を提供します。これでも十分ではない場合、atomic
クラス、独自のカスタム Queue
クラス、および LockSupport
ブロックサポートを使用して、シンクロナイザを低レベルから構築できます。
次に、値ゼロを使用してロック解除状態およびロック状態を表す再入不可能な相互排他ロッククラスを示します。再入不可能なロックでは、厳密には現在の所有者スレッドを記録する必要はありませんが、このクラスでは使用状況を簡単に監視できるように、記録を行います。これは、状態のサポートおよびいずれかの計測メソッドの公開も行います。
class Mutex implements Lock, java.io.Serializable { // Our internal helper class private static class Sync extends AbstractQueuedSynchronizer { // Report whether in locked state protected boolean isHeldExclusively() { return getState() == 1; } // Acquire the lock if state is zero public boolean tryAcquire(int acquires) { assert acquires == 1; // Otherwise unused if (compareAndSetState(0, 1)) { setExclusiveOwnerThread(Thread.currentThread()); return true; } return false; } // Release the lock by setting state to zero protected boolean tryRelease(int releases) { assert releases == 1; // Otherwise unused if (getState() == 0) throw new IllegalMonitorStateException(); setExclusiveOwnerThread(null); setState(0); return true; } // Provide a Condition Condition newCondition() { return new ConditionObject(); } // Deserialize properly private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException { s.defaultReadObject(); setState(0); // reset to unlocked state } } // The sync object does all the hard work.We just forward to it. private final Sync sync = new Sync(); public void lock() { sync.acquire(1); } public boolean tryLock() { return sync.tryAcquire(1); } public void unlock() { sync.release(1); } public Condition newCondition() { return sync.newCondition(); } public boolean isLocked() { return sync.isHeldExclusively(); } public boolean hasQueuedThreads() { return sync.hasQueuedThreads(); } public void lockInterruptibly() throws InterruptedException { sync.acquireInterruptibly(1); } public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException { return sync.tryAcquireNanos(1, unit.toNanos(timeout)); } }
次に、起動に単一の signal を必要とすることを除き、CountDownLatch
クラスに類似したラッチクラスを示します。ラッチは非排他的であるため、shared 取得および解放メソッドを使用します。
class BooleanLatch { private static class Sync extends AbstractQueuedSynchronizer { boolean isSignalled() { return getState() != 0; } protected int tryAcquireShared(int ignore) { return isSignalled()? 1 : -1; } protected boolean tryReleaseShared(int ignore) { setState(1); return true; } } private final Sync sync = new Sync(); public boolean isSignalled() { return sync.isSignalled(); } public void signal() { sync.releaseShared(1); } public void await() throws InterruptedException { sync.acquireSharedInterruptibly(1); } }
入れ子のクラスの概要 | |
---|---|
class |
AbstractQueuedSynchronizer.ConditionObject
Lock 実装の基盤として機能する AbstractQueuedSynchronizer の Condition 実装です。 |
コンストラクタの概要 | |
---|---|
protected |
AbstractQueuedSynchronizer()
ゼロの初期同期状態を使用して、新規 AbstractQueuedSynchronizer インスタンスを作成します。 |
メソッドの概要 | |
---|---|
void |
acquire(int arg)
割り込みを無視して、排他モードで取得します。 |
void |
acquireInterruptibly(int arg)
排他モードで取得します。 |
void |
acquireShared(int arg)
割り込みを無視して、共有モードで取得します。 |
void |
acquireSharedInterruptibly(int arg)
共有モードで取得します。 |
protected boolean |
compareAndSetState(int expect,
int update)
現在の状態値が予想される値に等しい場合、同期状態を指定された更新値に原子的に設定します。 |
Collection<Thread> |
getExclusiveQueuedThreads()
排他モードで取得するために待機中のスレッドを含むコレクションを返します。 |
Thread |
getFirstQueuedThread()
キュー内の最初の (待機時間のもっとも長い) スレッドを返します。 |
Collection<Thread> |
getQueuedThreads()
取得を待機しているスレッドを含むコレクションを返します。 |
int |
getQueueLength()
取得を待機しているスレッドの推定数を返します。 |
Collection<Thread> |
getSharedQueuedThreads()
共有モードで取得するために待機中のスレッドを含むコレクションを返します。 |
protected int |
getState()
同期状態の現在値を返します。 |
Collection<Thread> |
getWaitingThreads(AbstractQueuedSynchronizer.ConditionObject condition)
このシンクロナイザに関連付けられた指定の状態で待機中のスレッドを含むコレクションを返します。 |
int |
getWaitQueueLength(AbstractQueuedSynchronizer.ConditionObject condition)
このシンクロナイザに関連付けられた指定の状態で待機しているスレッドの推定数を返します。 |
boolean |
hasContended()
このシンクロナイザの取得で競合しているスレッドが存在するかどうか (つまり、acquire メソッドがブロックされたかどうか) を照会します。 |
boolean |
hasQueuedThreads()
取得を待機中のスレッドが存在するかどうかを照会します。 |
boolean |
hasWaiters(AbstractQueuedSynchronizer.ConditionObject condition)
このシンクロナイザに関連付けられた指定の状態で待機しているスレッドが存在するかどうかを照会します。 |
protected boolean |
isHeldExclusively()
現在の (呼び出し側の) スレッドに関して、同期が排他的に行われる場合は true を返します。 |
boolean |
isQueued(Thread thread)
指定されたスレッドが、現在キューに入っている場合は true を返します。 |
boolean |
owns(AbstractQueuedSynchronizer.ConditionObject condition)
指定された ConditionObject がこのシンクロナイザをロックとして使用するかどうかを照会します。 |
boolean |
release(int arg)
排他モードで解放します。 |
boolean |
releaseShared(int arg)
共有モードで解放します。 |
protected void |
setState(int newState)
同期状態の値を設定します。 |
String |
toString()
シンクロナイザおよびその状態を識別する文字列を返します。 |
protected boolean |
tryAcquire(int arg)
排他モードでの取得を試みます。 |
boolean |
tryAcquireNanos(int arg,
long nanosTimeout)
排他モードで取得を試みます。 |
protected int |
tryAcquireShared(int arg)
共有モードでの取得を試みます。 |
boolean |
tryAcquireSharedNanos(int arg,
long nanosTimeout)
共有モードで取得を試みます。 |
protected boolean |
tryRelease(int arg)
排他モードでの解放を反映するように、状態の設定を試みます。 |
protected boolean |
tryReleaseShared(int arg)
共有モードでの解放を反映するように、状態の設定を試みます。 |
クラス java.util.concurrent.locks.AbstractOwnableSynchronizer から継承されたメソッド |
---|
getExclusiveOwnerThread, setExclusiveOwnerThread |
クラス java.lang.Object から継承されたメソッド |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
コンストラクタの詳細 |
---|
protected AbstractQueuedSynchronizer()
メソッドの詳細 |
---|
protected final int getState()
protected final void setState(int newState)
newState
- 新規状態値protected final boolean compareAndSetState(int expect, int update)
expect
- 予想される値update
- 新しい値
protected boolean tryAcquire(int arg)
このメソッドは常に取得を実行するスレッドにより呼び出されます。このメソッドが失敗をレポートし、かつスレッドがキューに入れられていない場合、取得メソッドは、ほかのスレッドからの解放により信号が送信されるまでそのスレッドをキューに入れることができます。これは、Lock.tryLock()
メソッドの実装に使用できます。
デフォルト実装は、UnsupportedOperationException
をスローします。
arg
- acquire の引数。この値は、常に acquire メソッドに渡される値、または状態待機へのエントリで保存される値になる。
それ以外の場合、この値は未解釈となり、任意の値を表すことができる
true
。成功時には、このオブジェクトは取得済みである
IllegalMonitorStateException
- 取得により、このシンクロナイザが不正な状態に置かれる場合。
同期が正しく機能するためには、この例外を一貫した方式でスローする必要がある
UnsupportedOperationException
- 排他モードがサポートされていない場合protected boolean tryRelease(int arg)
このメソッドは、解放を実行するスレッドにより常に呼び出されます。
デフォルト実装は、UnsupportedOperationException
をスローします。
arg
- release の引数。この値は、常に release メソッドに渡される値、または状態待機へのエントリでの現在の状態値になる。
それ以外の場合、この値は未解釈となり、任意の値を表すことができる
true
、そうでない場合は false
IllegalMonitorStateException
- 解放により、このシンクロナイザが不正な状態に置かれる場合。
同期が正しく機能するためには、この例外を一貫した方式でスローする必要がある
UnsupportedOperationException
- 排他モードがサポートされていない場合protected int tryAcquireShared(int arg)
このメソッドは常に取得を実行するスレッドにより呼び出されます。このメソッドが失敗をレポートし、かつスレッドがキューに入れられていない場合、取得メソッドは、ほかのスレッドからの解放により信号が送信されるまでそのスレッドをキューに入れることができます。
デフォルト実装は、UnsupportedOperationException
をスローします。
arg
- acquire の引数。この値は、常に acquire メソッドに渡される値、または状態待機へのエントリで保存される値になる。
それ以外の場合、この値は未解釈となり、任意の値を表すことができる
IllegalMonitorStateException
- 取得により、このシンクロナイザが不正な状態に置かれる場合。
同期が正しく機能するためには、この例外を一貫した方式でスローする必要がある
UnsupportedOperationException
- 共有モードがサポートされていない場合protected boolean tryReleaseShared(int arg)
このメソッドは、解放を実行するスレッドにより常に呼び出されます。
デフォルト実装は、UnsupportedOperationException
をスローします。
arg
- release の引数。この値は、常に release メソッドに渡される値、または状態待機へのエントリでの現在の状態値になる。
それ以外の場合、この値は未解釈となり、任意の値を表すことができる
true
、そうでない場合は false
IllegalMonitorStateException
- 解放により、このシンクロナイザが不正な状態に置かれる場合。
同期が正しく機能するためには、この例外を一貫した方式でスローする必要がある
UnsupportedOperationException
- 共有モードがサポートされていない場合protected boolean isHeldExclusively()
true
を返します。非待機状態の AbstractQueuedSynchronizer.ConditionObject
メソッドが呼び出されるごとに、このメソッドが呼び出されます (待機状態のメソッドでは release(int)
が呼び出される)。
デフォルト実装は、UnsupportedOperationException
をスローします。このメソッドは、AbstractQueuedSynchronizer.ConditionObject
メソッドで内部的にのみ呼び出されるため、状態が使用されない場合は定義する必要がありません。
true
、そうでない場合は false
UnsupportedOperationException
- 状態がサポートされない場合public final void acquire(int arg)
tryAcquire(int)
を呼び出すことで実装され、成功時に復帰します。それ以外の場合、スレッドはキューに入れられ、たいていの場合ブロックおよびブロック解除を何度も繰り返し、成功するまで tryAcquire(int)
を呼び出します。このメソッドは、Lock.lock()
メソッドの実装に使用できます。
arg
- acquire の引数。この値は tryAcquire(int)
に送信されるが、それ以外の場合は未解釈となり、任意の値を表すことができるpublic final void acquireInterruptibly(int arg) throws InterruptedException
tryAcquire(int)
を呼び出すことで実装され、成功時に復帰します。それ以外の場合、スレッドはキューに入れられ、たいていの場合ブロックおよびブロック解除を何度も繰り返し、成功するかスレッドで割り込みが発生するまで tryAcquire(int)
を呼び出します。このメソッドは、Lock.lockInterruptibly()
メソッドの実装に使用できます。
arg
- acquire の引数。この値は tryAcquire(int)
に送信されるが、それ以外の場合は未解釈となり、任意の値を表すことができる
InterruptedException
- 現在のスレッドで割り込みが発生した場合public final boolean tryAcquireNanos(int arg, long nanosTimeout) throws InterruptedException
tryAcquire(int)
を呼び出すことで実装され、成功時に復帰します。それ以外の場合、スレッドはキューに入れられ、たいていの場合ブロックおよびブロック解除を何度も繰り返し、成功するかスレッドで割り込みが発生するか、タイムアウト時間が経過するまで tryAcquire(int)
を呼び出します。このメソッドは、Lock.tryLock(long, TimeUnit)
メソッドの実装に使用できます。
arg
- acquire の引数。この値は tryAcquire(int)
に送信されるが、それ以外の場合は未解釈となり、任意の値を表すことができるnanosTimeout
- 待機する最大ナノ秒数
true
、タイムアウトした場合は false
InterruptedException
- 現在のスレッドで割り込みが発生した場合public final boolean release(int arg)
tryRelease(int)
が true を返す場合、1 つ以上のスレッドをブロック解除することで実装されます。このメソッドは、Lock.unlock()
メソッドの実装で使用できます。
arg
- release の引数。この値は tryRelease(int)
に送信されるが、それ以外の場合は未解釈となり、任意の値を表すことができる
tryRelease(int)
から返される値public final void acquireShared(int arg)
tryAcquireShared(int)
を呼び出すことで実装され、成功時に復帰します。それ以外の場合、スレッドはキューに入れられ、たいていの場合ブロックおよびブロック解除を何度も繰り返し、成功するまで tryAcquireShared(int)
を呼び出します。
arg
- acquire の引数。この値は tryAcquireShared(int)
に送信されるが、それ以外の場合は未解釈となり、任意の値を表すことができるpublic final void acquireSharedInterruptibly(int arg) throws InterruptedException
tryAcquireShared(int)
を呼び出すことで実装され、成功時に復帰します。それ以外の場合、スレッドはキューに入れられ、たいていの場合ブロックおよびブロック解除を何度も繰り返し、成功するかスレッドで割り込みが発生するまで tryAcquireShared(int)
を呼び出します。
arg
- acquire の引数。
この値は tryAcquireShared(int)
に送信されるが、それ以外の場合は未解釈となり、任意の値を表すことができる
InterruptedException
- 現在のスレッドで割り込みが発生した場合public final boolean tryAcquireSharedNanos(int arg, long nanosTimeout) throws InterruptedException
tryAcquireShared(int)
を呼び出すことで実装され、成功時に復帰します。それ以外の場合、スレッドはキューに入れられ、たいていの場合ブロックおよびブロック解除を何度も繰り返し、成功するか、スレッドで割り込みが発生するか、タイムアウト時間が経過するまで tryAcquireShared(int)
を呼び出します。
arg
- acquire の引数。この値は tryAcquireShared(int)
に送信されるが、それ以外の場合は未解釈となり、任意の値を表すことができるnanosTimeout
- 待機する最大ナノ秒数
true
、タイムアウトした場合は false
InterruptedException
- 現在のスレッドで割り込みが発生した場合public final boolean releaseShared(int arg)
tryReleaseShared(int)
が true を返す場合、1 つ以上のスレッドをブロック解除することで実装されます。
arg
- release の引数。この値は tryReleaseShared(int)
に送信されるが、それ以外の場合は未解釈となり、任意の値を表すことができる
tryReleaseShared(int)
から返される値public final boolean hasQueuedThreads()
true
が返されてもほかのスレッドが取得を実行することは保証されません。
この実装では、この操作は一定の時間で復帰します。
true
public final boolean hasContended()
この実装では、この操作は一定の時間で復帰します。
true
public final Thread getFirstQueuedThread()
null
を返します。
通常、この実装では、この操作は一定時間で復帰します。ただし、ほかのスレッドがキューの変更を並行して実行している場合は、競合により処理を繰り返す場合があります。
null
public final boolean isQueued(Thread thread)
この実装は、キューをトラバースして指定されたスレッドの存在を判別します。
thread
- スレッド
true
NullPointerException
- スレッドが null の場合public final int getQueueLength()
public final Collection<Thread> getQueuedThreads()
public final Collection<Thread> getExclusiveQueuedThreads()
getQueuedThreads()
と同じプロパティーを保持します。
public final Collection<Thread> getSharedQueuedThreads()
getQueuedThreads()
と同じプロパティーを保持します。
public String toString()
"State ="
に続いて getState()
の現在値、およびキューが空かどうかに応じて "nonempty"
または "empty"
が含まれます。
Object
内の toString
public final boolean owns(AbstractQueuedSynchronizer.ConditionObject condition)
condition
- 状態
NullPointerException
- condition が null の場合public final boolean hasWaiters(AbstractQueuedSynchronizer.ConditionObject condition)
condition
- 状態
IllegalMonitorStateException
- 排他的同期が保持されない場合
IllegalArgumentException
- 指定された状態がこのシンクロナイザと関連付けられていない場合
NullPointerException
- condition が null の場合public final int getWaitQueueLength(AbstractQueuedSynchronizer.ConditionObject condition)
condition
- 状態
IllegalMonitorStateException
- 排他的同期が保持されない場合
IllegalArgumentException
- 指定された状態がこのシンクロナイザと関連付けられていない場合
NullPointerException
- condition が null の場合public final Collection<Thread> getWaitingThreads(AbstractQueuedSynchronizer.ConditionObject condition)
condition
- 状態
IllegalMonitorStateException
- 排他的同期が保持されない場合
IllegalArgumentException
- 指定された状態がこのシンクロナイザと関連付けられていない場合
NullPointerException
- condition が null の場合
|
JavaTM Platform Standard Ed. 6 |
|||||||||
前のクラス 次のクラス | フレームあり フレームなし | |||||||||
概要: 入れ子 | フィールド | コンストラクタ | メソッド | 詳細: フィールド | コンストラクタ | メソッド |
Copyright 2006 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms. Documentation Redistribution Policy も参照してください。