写的很乱,ReentrantReadWriteLock调来调去的。不懂或者有错误欢迎留言
加锁
public void lock() {
sync
.acquireShared(1);
}
public final void acquireShared(int arg
) {
if (tryAcquireShared(arg
) < 0)
doAcquireShared(arg
);
}
tryAcquireShared方法
protected final int tryAcquireShared(int unused
) {
Thread current
= Thread
.currentThread();
int c
= getState();
if (exclusiveCount(c
) != 0 &&
getExclusiveOwnerThread() != current
)
return -1;
int r
= sharedCount(c
);
if (!readerShouldBlock() &&
r
< MAX_COUNT
&&
compareAndSetState(c
, c
+ SHARED_UNIT
)) {
if (r
== 0) {
firstReader
= current
;
firstReaderHoldCount
= 1;
} else if (firstReader
== current
) {
firstReaderHoldCount
++;
} else {
HoldCounter rh
= cachedHoldCounter
;
if (rh
== null
|| rh
.tid
!= getThreadId(current
))
cachedHoldCounter
= rh
= readHolds
.get();
else if (rh
.count
== 0)
readHolds
.set(rh
);
rh
.count
++;
}
return 1;
}
return fullTryAcquireShared(current
);
}
readerShouldBlock方法
final boolean readerShouldBlock() {
return apparentlyFirstQueuedIsExclusive();
}
final boolean readerShouldBlock() {
return hasQueuedPredecessors();
}
apparentlyFirstQueuedIsExclusive方法
final boolean apparentlyFirstQueuedIsExclusive() {
Node h
, s
;
return (h
= head
) != null
&&
(s
= h
.next
) != null
&&
!s
.isShared() &&
s
.thread
!= null
;
}
fullTryAcquireShared方法
final int fullTryAcquireShared(Thread current
) {
HoldCounter rh
= null
;
for (;;) {
int c
= getState();
if (exclusiveCount(c
) != 0) {
if (getExclusiveOwnerThread() != current
)
return -1;
} else if (readerShouldBlock()) {
if (firstReader
== current
) {
} else {
if (rh
== null
) {
rh
= cachedHoldCounter
;
if (rh
== null
|| rh
.tid
!= getThreadId(current
)) {
rh
= readHolds
.get();
if (rh
.count
== 0)
readHolds
.remove();
}
}
if (rh
.count
== 0)
return -1;
}
}
if (sharedCount(c
) == MAX_COUNT
)
throw new Error("Maximum lock count exceeded");
if (compareAndSetState(c
, c
+ SHARED_UNIT
)) {
if (sharedCount(c
) == 0) {
firstReader
= current
;
firstReaderHoldCount
= 1;
} else if (firstReader
== current
) {
firstReaderHoldCount
++;
} else {
if (rh
== null
)
rh
= cachedHoldCounter
;
if (rh
== null
|| rh
.tid
!= getThreadId(current
))
rh
= readHolds
.get();
else if (rh
.count
== 0)
readHolds
.set(rh
);
rh
.count
++;
cachedHoldCounter
= rh
;
}
return 1;
}
}
}
doAcquireShared方法
private void doAcquireShared(int arg
) {
final Node node
= addWaiter(Node
.SHARED
);
boolean failed
= true;
try {
boolean interrupted
= false;
for (;;) {
final Node p
= node
.predecessor();
if (p
== head
) {
int r
= tryAcquireShared(arg
);
if (r
>= 0) {
setHeadAndPropagate(node
, r
);
p
.next
= null
;
if (interrupted
)
selfInterrupt();
failed
= false;
return;
}
}
if (shouldParkAfterFailedAcquire(p
, node
) &&
parkAndCheckInterrupt())
interrupted
= true;
}
} finally {
if (failed
)
cancelAcquire(node
);
}
setHeadAndPropagate方法
private void setHeadAndPropagate(Node node
, int propagate
) {
Node h
= head
;
setHead(node
);
if (propagate
> 0 || h
== null
|| h
.waitStatus
< 0 ||
(h
= head
) == null
|| h
.waitStatus
< 0) {
Node s
= node
.next
;
if (s
== null
|| s
.isShared())
doReleaseShared();
}
}
doReleaseShared方法
private void doReleaseShared() {
for (;;) {
Node h
= head
;
if (h
!= null
&& h
!= tail
) {
int ws
= h
.waitStatus
;
if (ws
== Node
.SIGNAL
) {
if (!compareAndSetWaitStatus(h
, Node
.SIGNAL
, 0))
continue;
unparkSuccessor(h
);
}
else if (ws
== 0 &&
!compareAndSetWaitStatus(h
, 0, Node
.PROPAGATE
))
continue;
}
if (h
== head
)
break;
}
}
解锁过程
public void unlock() {
sync
.releaseShared(1);
}
public final boolean releaseShared(int arg
) {
if (tryReleaseShared(arg
)) {
doReleaseShared();
return true;
}
return false;
}
tryReleaseShared方法
protected final boolean tryReleaseShared(int unused
) {
Thread current
= Thread
.currentThread();
if (firstReader
== current
) {
if (firstReaderHoldCount
== 1)
firstReader
= null
;
else
firstReaderHoldCount
--;
} else {
HoldCounter rh
= cachedHoldCounter
;
if (rh
== null
|| rh
.tid
!= getThreadId(current
))
rh
= readHolds
.get();
int count
= rh
.count
;
if (count
<= 1) {
readHolds
.remove();
if (count
<= 0)
throw unmatchedUnlockException();
}
--rh
.count
;
}
for (;;) {
int c
= getState();
int nextc
= c
- SHARED_UNIT
;
if (compareAndSetState(c
, nextc
))
return nextc
== 0;
}
}
转载请注明原文地址: https://lol.8miu.com/read-38474.html