ReentrantReadWriteLock写锁尝试获取锁
protected final boolean tryAcquire(int acquires) {
/*
* Walkthrough:
* 1. If read count nonzero or write count nonzero
* and owner is a different thread, fail.
* 2. If count would saturate, fail. (This can only
* happen if count is already nonzero.)
* 3. Otherwise, this thread is eligible for lock if
* it is either a reentrant acquire or
* queue policy allows it. If so, update state
* and set owner.
*/
Thread current = Thread.currentThread();
// 获取锁的状态
int c = getState();
// 获取锁中写的状态
int w = exclusiveCount(c);
/**
* 如果c不为0,说明锁已经被某个线程持有,当然有可能是当前线程(重入)。
*/
if (c != 0) {
// (Note: if c != 0 and w == 0 then shared count != 0)
/**
* w == 0, 说明没有写锁,即使是当前线程持有,无法获取到锁,
* 因为锁不支持升级,所以返回false
*
* 走到第二个条件,说明是有写锁
* 判断重入:current != getExclusiveOwnerThread()
* 判断时否为当前线程,如果不是,则返回false
*/
if (w == 0 || current != getExclusiveOwnerThread())
return false;
/**
* 判断是否大于最大重入次数,最大次数:2^16-1
*/
if (w + exclusiveCount(acquires) > MAX_COUNT)
throw new Error("Maximum lock count exceeded");
// Reentrant acquire
// 锁的次数+1(state:readLock(16位2进制)| writeLock(16位2进制))
setState(c + acquires);
return true;
}
/**
* c == 0 没有被人持有
* writerShouldBlock()作用:判断是否需要排队,通过队列中是否存在线程
* 1.非公平锁,不管是否有线程排队,都返回false(不需要排队)
* 2.公平锁,判断队列中是否存在线程,如果有,就排队。
* (跳过第二条执行,直接返回false);反之(执行第二条语句)
*
* !compareAndSetState(c, c + acquires)作用:获取锁,如果获取不到锁,返回false
*/
if (writerShouldBlock() ||
!compareAndSetState(c, c + acquires))
return false;
// 加锁成功,把锁中的线程,设置为当前线程。
setExclusiveOwnerThread(current);
return true;
}
网友评论