ReentrantReadWriteLock
4459 ワード
最近javaのロックを検討したところ,読み書きロックのコードを見るとjavadocでこのクラスについての解釈が理解しにくいことが分かった.そこで自分でコードに対して理解して、ここで記録して、一部の地方はあまりはっきり見えないで、もし間違いがあれば訂正してください.
異なる視点からロックを見ると、ロックには以下の特性があります.
公平性:
≪フェア・ロックと非フェア・ロック|フェア・ロック|emdw≫:ロックを取得する順序がリクエスト・ロックの順序で行われている場合は、フェア・ロックです.そうでない場合は、非フェア・ロックです.
反発性:
排他ロックと共有ロック:排他ロックは1つのスレッドのみが保持でき、排他ロックが再ロック可能(同じスレッドで複数回取得可能)である場合、同じ一線
プログラムは複数回取得できます.
共有ロックは、複数のスレッドで取得できます.
ReentrantReadWriteLockは、ロックの同時性を向上させ、読み取り、読み取り、書き込み、反発を高めることができます.非公平ロックは待機時間が最も優先されます
長いその書き込みスレッドは書き込みロックを割り当てる(非公平な読み取りロックの実現によって決定される).
読み書きロックの公平性:
非公平リードロック:非公平リードがリードロックを取得する場合、キューヘッダノードが独占ノードであるか否かを判断し、スピン待機する.
非公平書き込みロック:非公平書き込みロックを取得する場合は、書き込みロックを直接取得してみます.
≪フェア・リード・ロック|フェア・リード・ロック|emdw≫:キューを待つヘッダ・ノードでない場合、リード・ロックは取得できません.
≪フェア・ライト・ロック|フェア・ライト・ロック|emdw≫:キューを待つヘッダ・ノードでない場合、ライト・ロックは取得できません.
ロックのダウングレード:
ロックのダウングレードによるロックの取得順序:
writelock.lock();
readlock.lock();
writelock.unlock();
readlock.unlock();
ロックダウングレードで書き込みロックを取得すると、スレッドがあっても読み取りロックを取得できません.データの変更が完了すると、現在のスレッドが読み取りロックを取得した後、操作を続行できます.
他の書き込みスレッドはロックを取得できないため、他の書き込みスレッドには影響されません.
ロックのアップグレード:
ロックのアップグレードは許可されていません.ここでソースコードを見ると困惑しますが、コードには実際にロックを取ることができます.でも、ここにある
ロックのアップグレードによってロックが取得される順序は次のとおりです.
readlock.lock();
writelock.lock();
readlock.unlock();
writelock.unlock();
なぜデッドロックなの?
ライトロックを取得するには、すべてのリードロックを解放する必要があるため、複数のスレッドが同時にリードロックを取得してライトロックを取得すると、ライトロックを取得する場所でリードが待機します.
ロックが解除され、デッドロックが発生します.
異なる視点からロックを見ると、ロックには以下の特性があります.
公平性:
≪フェア・ロックと非フェア・ロック|フェア・ロック|emdw≫:ロックを取得する順序がリクエスト・ロックの順序で行われている場合は、フェア・ロックです.そうでない場合は、非フェア・ロックです.
反発性:
排他ロックと共有ロック:排他ロックは1つのスレッドのみが保持でき、排他ロックが再ロック可能(同じスレッドで複数回取得可能)である場合、同じ一線
プログラムは複数回取得できます.
共有ロックは、複数のスレッドで取得できます.
ReentrantReadWriteLockは、ロックの同時性を向上させ、読み取り、読み取り、書き込み、反発を高めることができます.非公平ロックは待機時間が最も優先されます
長いその書き込みスレッドは書き込みロックを割り当てる(非公平な読み取りロックの実現によって決定される).
読み書きロックの公平性:
非公平リードロック:非公平リードがリードロックを取得する場合、キューヘッダノードが独占ノードであるか否かを判断し、スピン待機する.
非公平書き込みロック:非公平書き込みロックを取得する場合は、書き込みロックを直接取得してみます.
≪フェア・リード・ロック|フェア・リード・ロック|emdw≫:キューを待つヘッダ・ノードでない場合、リード・ロックは取得できません.
≪フェア・ライト・ロック|フェア・ライト・ロック|emdw≫:キューを待つヘッダ・ノードでない場合、ライト・ロックは取得できません.
ロックのダウングレード:
ロックのダウングレードによるロックの取得順序:
writelock.lock();
readlock.lock();
writelock.unlock();
readlock.unlock();
ロックダウングレードで書き込みロックを取得すると、スレッドがあっても読み取りロックを取得できません.データの変更が完了すると、現在のスレッドが読み取りロックを取得した後、操作を続行できます.
他の書き込みスレッドはロックを取得できないため、他の書き込みスレッドには影響されません.
ロックのアップグレード:
ロックのアップグレードは許可されていません.ここでソースコードを見ると困惑しますが、コードには実際にロックを取ることができます.でも、ここにある
ロックのアップグレードによってロックが取得される順序は次のとおりです.
readlock.lock();
writelock.lock();
readlock.unlock();
writelock.unlock();
なぜデッドロックなの?
ライトロックを取得するには、すべてのリードロックを解放する必要があるため、複数のスレッドが同時にリードロックを取得してライトロックを取得すると、ライトロックを取得する場所でリードが待機します.
ロックが解除され、デッドロックが発生します.
// 16 , 16
static final int SHARED_SHIFT = 16;
static final int SHARED_UNIT = (1 << SHARED_SHIFT);
//
static final int MAX_COUNT = (1 << SHARED_SHIFT) - 1;
static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1;
//
static int sharedCount(int c) { return c >>> SHARED_SHIFT; }
//
static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; }
/**
**/
protected final boolean tryAcquire(int acquires) {
Thread current = Thread.currentThread();
int c = getState();
int w = exclusiveCount(c);
if (c != 0) {
// (Note: if c != 0 and w == 0 then shared count != 0)
if (w == 0 || current != getExclusiveOwnerThread())
return false;
if (w + exclusiveCount(acquires) > MAX_COUNT)
throw new Error("Maximum lock count exceeded");
}
if ((w == 0 && writerShouldBlock(current)) ||
!compareAndSetState(c, c + acquires))
return false;
setExclusiveOwnerThread(current);
return true;
}
1. c 0,w 0, ,
2. c 0, ,
3. w 0( ),
4. , true
5. c 0, true
/**
**/
protected final int tryAcquireShared(int unused) {
Thread current = Thread.currentThread();
int c = getState();
if (exclusiveCount(c) != 0 &&
getExclusiveOwnerThread() != current)
return -1;
if (sharedCount(c) == MAX_COUNT)
throw new Error("Maximum lock count exceeded");
if (!readerShouldBlock(current) &&
compareAndSetState(c, c + SHARED_UNIT)) {
HoldCounter rh = cachedHoldCounter;
if (rh == null || rh.tid != current.getId())
cachedHoldCounter = rh = readHolds.get();
rh.count++;
return 1;
}
return fullTryAcquireShared(current);
}
1. ,
2. ,
3. , , ,
, ,