ReentrantLock.png
FairSync
lock
final void lock() {
// 可以跟非公平锁做对比,这里会去调用acquire来通过公平原则来加锁
acquire(1);
}
tryAcquire
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
// 等于0,说明锁还没有被其他线程持有
if (c == 0) {
// 当hasQueuedPredecessors为false的情况才会去拿锁,也就是队列中第一个等待的当前线程
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);
return true;
}
return false;
}
public final boolean hasQueuedPredecessors() {
// The correctness of this depends on head being initialized
// before tail and on head.next being accurate if the current
// thread is first in queue.
Node t = tail; // Read fields in reverse initialization order
Node h = head;
Node s;
// 而这里返回false的情况也就两种
// 1. head=tail,说明队列还没有waiter
// 2. 队列中有waiter,且当前线程是第一个
return h != t &&
((s = h.next) == null || s.thread != Thread.currentThread());
}
NonfairSync
lock
final void lock() {
// 非公平锁的意义在于,谁先来,谁抢锁。所以,这里一上来直接试着抢锁,如果能抢到,最好不过了。
// 直接设置为当前线程
// 如果没抢到,那没办法,走非公平锁的正常流程
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
tryAcquire
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
// 等于0,说明锁还没有被其他线程持有
if (c == 0) {
// 可以跟公平锁比较下,这里不会去看是否是队列的第一个,直接去拿锁,谁先拿到谁独占
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
// 下面还是重入锁的计数逻辑
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
tryRelease
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);
}
// 更新state
setState(c);
return free;
}
网友评论