ReentrantLock 解析
2019-04-26 本文已影响0人
Wi1ls努力努力再努力
public ReentrantLock() {
sync = new NonfairSync();
}
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
ReentrantLock 有两种实现,公平锁 FairSync 和非公平锁NonfairSync;
用法
ReentrantLock lock = new ReentrantLock(true/false);
public void lockMethod(){
lock.lock();
...
lock.unlock();
}
则 lock.lock()和lock.unlock()则为获得锁和释放锁。
@ReentrantLock
public void lock(){
sync.lock();
}
//以公平锁分析
@FairSync
final void lock(){
acquire(1);
}
@AbstractQueuedSynchronizer
public final void acquire(int arg){
if(!tryAcquire(args) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg)){
selfInterrupt();
}
}
@FairSync
protected final boolean tryAcquire(int acquires) {
//获取当前线程
final Thread current = Thread.currentThread();
//获得 volatile state,如果是第一个进来的线程c 为 0,后面进来的线程如果锁还没有释放的话, c 为 1
int c = getState();
if (c == 0) {
//可以获得锁的线程,并且 CAS 操作设置 state 为 1
if (!hasQueuedPredecessors() &&
compareAndSetState(0, acquires)) {
//设置当前获得锁的线程
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
//如果 c 不为 0,说明锁被某个线程获得了,能进这里说明获取锁的线程也是当前线程,说明当前线程 lock()了两次,所以是可重入的,此时将 state 增加
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
//此时锁被其他线程获得了,则返回 false
return false;
}
@AbstractQueuedSynchronizer
//tryAcquire(args) 返回 true 说明获得锁成功,直接跳出去执行方法体
//tryAcquire(args)返回 false,则会进行 acquireQueued(addWaiter(Node.EXCLUSIVE), arg)
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
@AbstractQueuedSynchronizer
//将当前线程入队
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;
}
@AbstractQueuedSynchronizer
//进入死循环等待,每次会获取等待队列的第一个线程,执行tryAcquire(arg)尝试去获得锁,如果获得,则将 status 设置为 1,表示获得了锁
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);
}
}
释放锁
@ReentrantLock
public void unlock() {
sync.release(1);
}
@AbstractQueuedSynchronizer
public final boolean release(int arg) {
//尝试释放锁
if (tryRelease(arg)) {
Node h = head;
if (h != null && h.waitStatus != 0)
unparkSuccessor(h);
return true;
}
return false;
}
@ReentrantLock$Sync
protected final boolean tryRelease(int releases) {
//将锁的信号量-1
int c = getState() - releases;
//获得锁的线程和释放锁的线程不是同一个,抛异常
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
boolean free = false;
//如果自减后 c==0,则释放锁
if (c == 0) {
free = true;
setExclusiveOwnerThread(null);
}
//如果当前线程重入了多次,只把 status-1,线程会继续保留锁
setState(c);
return free;
}
@AbstractQueuedSynchronizer
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);
}
公平锁和非公平锁关键在于
@非公平锁,NonfairSync
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
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;
}
@FairSync
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);
return true;
}
return false;
}