RentrantrantLockソースのメモを読みます。
Reentrant Lockには以下のいくつかの特性があります。
基本的な取得ロック操作、基本的な解除ロック操作、ポーリング可能なロック取得操作、中断可能な取得ロック操作、タイミング取得ロック操作、公平キューを使用します。
まずReentrant Lockの実現は主に
AbstractQueuedSynchronizer。AbstractQueueuedSynchronizerは状態情報の単一整数を維持します。
stateここでstateを使用して、ロックを持つスレッドがロックの取得を要求する回数を表します。
state==0はロックが取得可能な状態を表します。
基本的な取得ロック操作:ロック()方法:
public void lock(){
sync.lock();
)
syncはReentrant Lock静的内部クラスSyncの一つの引用である。
パラメータなしの構造関数は、デフォルトのsyncがNonfairSync().(不公平なキュー)を指します。SyncはAbstractQueue dSynch ronizerを拡張しました。一方、NonfairSyncはSyncを拡張しました。
NonfairSyncにおけるロック()方法の実現は以下の通りである。
final void lock() {
if (compareAndSetState(0, 1))//AbstractQueuedSynchronizer ( ), state 0 state 1
setExclusiveOwnerThread(Thread.currentThread());//
else
acquire(1);// state++, , 。(AbstractQueuedSynchronizer )
}
ポーリング可能なロック取得動作:具体的には、
final boolean nonfairTryAcquire(int acquires) {// acquirs 1
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {// state 0
if (compareAndSetState(0, acquires)) {// , state 0, state 1.
setExclusiveOwnerThread(current);//
return true;
}
}
else if (current == getExclusiveOwnerThread()) {//
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);// state
return true;
}
return false;
}
基本的なロック解除操作:
protected final boolean tryRelease(int releases) {// releases 1
int c = getState() - releases;
if (Thread.currentThread() != getExclusiveOwnerThread()) // ,
throw new IllegalMonitorStateException();
boolean free = false;
if (c == 0) {//
free = true;
setExclusiveOwnerThread(null);//
}
setState(c);
return free;
}
公平なキューを使用する:公平なキューの取得ロック操作と非公平キュー取得ロック操作の主な違いは、現在のスレッドが列の最初の要素であるかどうかを判断するためのISFirst(current)が多くなっていることである。これにより、公平なキューが実現される。
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (isFirst(current) && //
compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
RentrantrantLockの実現は主にAbstractQue Synchronizerに依存しているが、Reentrant LockはAQSを拡張するのではなく、使用依頼であり、静的な内部クラスを使用している。このような利点は、クラスの清潔性を維持し、外部に公開する方法だけを露出することです。AQSを拡張すると、多すぎる方法が露出し、これらの方法は使用者が誤用しやすいです。