|
||||||||||
前のクラス 次のクラス | フレームあり フレームなし | |||||||||
概要: 入れ子 | フィールド | コンストラクタ | メソッド | 詳細: フィールド | コンストラクタ | メソッド |
java.lang.Objectjava.util.concurrent.locks.ReentrantLock
jp.terasoluna.fw.web.thin.LimitedLock
public class LimitedLock
ロック待ちスレッドが増えた際に、古いロック待ちスレッドを中断する機能を持つロッククラス。
Webにおいて、セッションで同期化する場合、synchronizedによる同期化実装では、 以下のような操作を行うユーザがいた場合に、 スレッドを無駄に占有してしまう(大量のスレッドがロック待ち状態になってしまう)問題がある。
このクラス内部の基本的なルールは以下の通りである。
このクラス内部の基本的な動作は以下の通りである。
例) しきい値が2のとき
スレッド1, 2, 3, 4の順でロックを要求した場合、 スレッド1がロックを取得し、スレッド2, 3, 4がロック待ちとなる。
このとき、ロック待ちスレッド(3)がしきい値(2)を超えているので、 さらにスレッド5がロックを要求したとき、 もっとも古いロック待ちスレッドである、スレッド2のロック待ちを中断し、 スレッド5がロック待ち状態となる。
ロックを取得したスレッドがロックを返すまでの間、 別のスレッドが順次、次々とロックを要求した場合(並行して要求しない場合)、 ロック待ちスレッド数は、しきい値と、しきい値+1の間を遷移する。
また、新たなロック要求がない期間においては、ロック待ちスレッド数は、しきい値+1となる。
ただし、並行して要求があった場合の、ロック待ちスレッド数の上限は保証しない。
また、外部で同期化してはならない。
(同期化すると、多数のスレッドをロック待ちにしてしまう事象を回避するという、このクラスの目的が果たせない。)
よって、ロック待ちスレッド数の上限は、ベストエフォートとなる。
このクラスでは、lockInterruptiblyメソッドでロックを取得し、 unlockメソッドでロックを解放する。
その他のロック制御メソッド(スーパークラスで用意されているメソッド)は使用しないこと。
ロック待ちが中断されたスレッドは、 lockInterruptiblyメソッドを実行中に、InterruptedExceptionが発生することにより、 ロック待ち状態から復帰する。
このクラスの中断(スレッド割り込み)機構により、InterruptedExceptionが発生した場合、 スレッドの割り込みステータスはクリアされる。
ただし、このクラスの外部からのスレッド割り込みがある場合には、このクラスの処理を抜けた際の スレッドの割り込みステータスは不定である。
外部割り込みのタイミングによっては、 InterruptedExceptionが発生しつつ、割り込みステータスも設定されている状態となることがある。
(InterruptedException発生後、割り込みステータスクリアコードが実行された後に、外部割り込みが発生した場合が該当。)
コード記述例:
LimitedLock lock;
… 同期化したい範囲で共有するLimitedLockインスタンスを取得
try {
lock.lockInterruptibly();
… ロック取得後の処理
} catch (InterruptedException e) {
… ロック待ち中断時の処理
} finally {
lock.unlock(); // ロックの取得に成功したか失敗したかの事前判定は不要。(内部で自動判定)
}
このクラスは、スーパークラスでSerializableが実装されているため、直列化可能な実装としているが、使い方次第では、このクラスの目的を果たすことが出来なくなる可能性が高いため、シリアライズ/デシリアライズの使用は推奨しない。 (セッションに格納することも推奨しない。) なお、デシリアライズ時は、スーパークラスと同様、シリアライズされたときの状態に関わらず、ロックが解除された状態となる。
ReentrantLock
,
直列化された形式コンストラクタの概要 | |
---|---|
LimitedLock(int threshold)
コンストラクタ。 |
メソッドの概要 | |
---|---|
void |
lockInterruptibly()
ロックを取得する。 |
void |
unlock()
ロックを解放する。 |
クラス java.util.concurrent.locks.ReentrantLock から継承されたメソッド |
---|
getHoldCount, getOwner, getQueuedThreads, getQueueLength, getWaitingThreads, getWaitQueueLength, hasQueuedThread, hasQueuedThreads, hasWaiters, isFair, isHeldByCurrentThread, isLocked, lock, newCondition, toString, tryLock, tryLock |
クラス java.lang.Object から継承されたメソッド |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
コンストラクタの詳細 |
---|
public LimitedLock(int threshold)
threshold
- しきい値(0以下の場合は、0として扱う)メソッドの詳細 |
---|
public void lockInterruptibly() throws InterruptedException
現在のスレッドがロックが取得できるか、他のスレッドが現在のスレッドに割り込みを行うまで、現在のスレッドは待機する。
現在のスレッドがロックが取得できた場合、メソッドを復帰する。
他のスレッドが現在のスレッドに割り込みを行った場合、InterruptedExceptionがスローされ、現在のスレッドの割り込みステータスがクリアされる。
(ただし、クラス外部からの割り込みがあった場合は、割り込みステータスは不定。)
上記は、スーパークラスによるもの。拡張ポイントは以下の通り。
Lock
内の lockInterruptibly
ReentrantLock
内の lockInterruptibly
InterruptedException
- 現在のスレッドで割り込みが発生した場合(このクラスの機能により、ロック待ちが中断された場合を含む)ReentrantLock.lockInterruptibly()
public void unlock()
現在のスレッドがこのロックのホルダである場合、スーパークラスのメソッドにより、ロックを解放する。
このクラスでの拡張ポイントは以下の通り。
・このロックのホルダでないスレッドがこのメソッドを実行しても、例外をスローしない。(何もせずに復帰する)
Lock
内の unlock
ReentrantLock
内の unlock
ReentrantLock.unlock()
|
||||||||||
前のクラス 次のクラス | フレームあり フレームなし | |||||||||
概要: 入れ子 | フィールド | コンストラクタ | メソッド | 詳細: フィールド | コンストラクタ | メソッド |