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 != current.getId())
cachedHoldCounter = rh = readHolds.get();
else
if
(rh.count ==
0
)
readHolds.set(rh);
rh.count++;
}
return
1
;
}
return
fullTryAcquireShared(current);
}
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 != current.getId()) {
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 != current.getId())
rh = readHolds.get();
else
if
(rh.count ==
0
)
readHolds.set(rh);
rh.count++;
cachedHoldCounter = rh;
}
return
1
;
}
}
}
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 != current.getId())
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
;
}
}
公平性策略公平与非公平策略是由 Sync 的子类 FairSync 和 NonfairSync 实现的。
/**
* 这个非公平策略的同步器是写锁优先的,申请写锁时总是不阻塞。
*/
static
final
class
NonfairSync
extends
Sync {
private
static
final
long
serialVersionUID = -8159625535654395037L;
final
boolean
writerShouldBlock() {
return
false
;
}
final
boolean
readerShouldBlock() {
static
final
class
FairSync
extends
Sync {
private
static
final
long
serialVersionUID = -2274990926593161451L;
final
boolean
writerShouldBlock() {
return
hasQueuedPredecessors();
}
final
boolean
readerShouldBlock() {
return
hasQueuedPredecessors();
}
}