构造方法生成公平与非公平锁
public
ReentrantLock(
boolean
fair) {
sync
= fair ?
new
FairSync() :
new
NonfairSync();
}
//上锁
public void
lock() {
sync
.lock();
}
先看公平锁
final void
lock() {
acquire(
1
);
}
进入
AbstractQueuedSynchronizer的
acquire(
1
)方法
public final void
acquire(
int
arg) {
if
(!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.
EXCLUSIVE
), arg))
selfInterrupt
();
}
先尝试
tryAcquire(arg)回到
ReentrantLock里面
protected final boolean
tryAcquire(
int
acquires) {
final
Thread current = Thread.
currentThread
();
//获得锁状态
int
c = getState();
if
(c ==
0
) {
//判断等待队列里是否有值有值则结束返回false
if
(!hasQueuedPredecessors() &&
//
否则尝试修改state
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"
);
//修改state的值
setState(nextc);
return true
;
}
return false
;
}
tryAcquire(arg)
在失败后执行
acquireQueued(addWaiter(Node.
EXCLUSIVE
), arg)
先看看
addWaiter(Node.
EXCLUSIVE
)
private
Node addWaiter(Node mode) {
//新建节点
Node node =
new
Node(Thread.
currentThread
(), mode);
// Try the fast path of enq; backup to full enq on failure
Node pred =
tail
;
//如果尾部tail不为空
if
(pred !=
null
) {
node.
prev
= pred;
//尝试着修改尾部失败了结束,成功了返回node
if
(compareAndSetTail(pred, node)) {
pred.
next
= node;
return
node;
}
}
//自旋修改
enq(node);
return
node;
}
进入
enq()
private
Node enq(
final
Node node) {
for
(;;) {
Node t =
tail
;
if
(t ==
null
) {
// Must initialize
//尾巴为空初始化,头等于尾,这边新建一个空的node来作为头,具体原因在
acquireQueued()
if
(compareAndSetHead(
new
Node()))
tail
=
head
;
}
else
{
node.
prev
= t;
//设置tail为node失败自旋
if
(compareAndSetTail(t, node)) {
t.
next
= node;
return
t;
}
}
}
}
返回之后再进入
acquireQueued(
final
Node node,
int
arg)
final boolean
acquireQueued(
final
Node node,
int
arg) {
boolean
failed =
true
;
try
{
boolean
interrupted =
false
;
for
(;;) {
//这个
node.predecessor里面的prev为空会报错,就是要新建一个空头
final
Node p = node.predecessor();
//当前线程前面一个判断是不是头,是的话
tryAcquire抢占用
if
(p ==
head
&& tryAcquire(arg)) {
setHead(node);
p.
next
=
null
;
// help GC
failed =
false
;
return
interrupted;
}
//判断要不要wait一下
if
(
shouldParkAfterFailedAcquire
(p, node) &&
parkAndCheckInterrupt())
interrupted =
true
;
}
}
finally
{
if
(failed)
//取消
cancelAcquire(node);
}
}
查看下
shouldParkAfterFailedAcquire
private static boolean
shouldParkAfterFailedAcquire(Node pred, Node node) {
int
ws = pred.
waitStatus
;
if
(ws == Node.
SIGNAL
)
//这个节点已经设置了请求释放信号的状态,这样它就可以安全地停车了
return true
;
if
(ws >
0
) {
//前面有取消的,就循环获得正常的
do
{
node.
prev
= pred = pred.
prev
;
}
while
(pred.
waitStatus
>
0
);
pred.
next
= node;
}
else
{
//waitStatus必须为0或传播。表明我们需要信号,但不要停车。访客需要重试,以确保在停车前不能获得。
compareAndSetWaitStatus
(pred, ws, Node.
SIGNAL
);
}
//返回重试,有可能已经释放了锁
return false
;
}
看一下
cancelAcquire(node)
private void
cancelAcquire(Node node) {
// Ignore if node doesn't exist
if
(node ==
null
)
return
;
node.
thread
=
null
;
// 跳过取消前任
Node pred = node.
prev
;
while
(pred.
waitStatus
>
0
)
node.
prev
= pred = pred.
prev
;
// predNext is the apparent node to unsplice. CASes below will
// fail if not, in which case, we lost race vs another cancel
// or signal, so no further action is necessary.
Node predNext = pred.
next
;
//当前节点状态设为
CANCELLED
node.
waitStatus
= Node.
CANCELLED
;
//
如果我们是尾巴,那就移走我们自己
.把刚才正常的作为尾巴
if
(node ==
tail
&& compareAndSetTail(node, pred)) {
compareAndSetNext
(pred, predNext,
null
);
}
else
{
//如果后续需要信号,试着设置pred的下一个链接,这样它就会得到一个。否则,唤醒它以传播。
//把取消的节点的下个设置到刚才正常的节点上面.
//如果跑到这边之后前面的节点也取消了,cas节点连接到取消的节点就继续循环
int
ws;
if
(pred !=
head
&&
((ws = pred.
waitStatus
) == Node.
SIGNAL
||
(ws <=
0
&&
compareAndSetWaitStatus
(pred, ws, Node.
SIGNAL
))) &&
pred.
thread
!=
null
) {
Node next = node.
next
;
if
(next !=
null
&& next.
waitStatus
<=
0
)
compareAndSetNext
(pred, predNext, next);
}
else
{
//唤醒下一个线程
unparkSuccessor(node);
}
node.
next
= node;
// help GC
}
}
解锁
public void
unlock() {
sync
.release(
1
);
}
private void
unparkSuccessor(Node node) {
int
ws = node.
waitStatus
;
if
(ws <
0
)
compareAndSetWaitStatus
(node, ws,
0
);
//找出下一个Node解锁
Node s = node.
next
;
if
(s ==
null
|| s.
waitStatus
>
0
) {
s =
null
;
for
(Node t =
tail
; t !=
null
&& t != node; t = t.
prev
)
if
(t.
waitStatus
<=
0
)
s = t;
}
if
(s !=
null
)
LockSupport.
unpark
(s.
thread
);
}
非公平锁
//非公平锁就是这边会先去cas枪战一下状态
final void
lock() {
if
(compareAndSetState(
0
,
1
))
setExclusiveOwnerThread(Thread.
currentThread
());
else
acquire(
1
);
}