构造函数
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
public ReentrantLock() {
sync = new NonfairSync();
}
ReentrantLock显示锁能找到的构造函数也就这两个了,默认的无参构造函数是代表建立一个非公平锁,有参数的构造函数可以显示指定公平锁(直接入队列排队等待)和非公平锁(先尝试加锁在入队列),本文主要从FairSync公平锁角度讲。
FairSync锁类图
加锁方法
final void lock() {
acquire(1);//尝试获取锁
}
public final void acquire(int arg) {
//tryAcquire(arg)由子类实现,获取锁方法
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {//锁未被占有,尝试占有
if (!hasQueuedPredecessors() &&
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);//重入次数加1
return true;
}
return false;
}
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;
if (pred != null) {//非初始化
node.prev = pred;
if (compareAndSetTail(pred, node)) {//入队列
pred.next = node;
return node;
}
}
enq(node);//为空时初始化,否则循环入队列直到成功
return node;
}
final boolean acquireQueued(final Node node, int arg) {
boolean failed = true;
try {
boolean interrupted = false;
for (;;) {
final Node p = node.predecessor();
if (p == head && tryAcquire(arg)) {//如果对象上一个为头结点,再次尝试获取锁
setHead(node);
p.next = null; // help GC
failed = false;
return interrupted;
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
interrupted = true;
}
} finally {
if (failed)
cancelAcquire(node);//撤销阻塞
}
}
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 {//将上一个节点的状态设置为signal,返回false,
compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
}
return false;
}
private final boolean parkAndCheckInterrupt() {
LockSupport.park(this);//当前线程阻塞
return Thread.interrupted();
}
加锁流程
底层加锁运用了LockSupport,LockSupport 流程
解锁方法
public void unlock() {
sync.release(1);
}
public final boolean release(int arg) {
if (tryRelease(arg)) {//当状态恢复空闲后才能为后续队列中线程发放许可
Node h = head;
if (h != null && h.waitStatus != 0)
unparkSuccessor(h);
return true;
}
return false;
}
protected final boolean tryRelease(int releases) {
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;
}
private void unparkSuccessor(Node node) {
int ws = node.waitStatus;
if (ws < 0)//等待状态恢复初始化
compareAndSetWaitStatus(node, ws, 0);
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);
}
解锁流程