ReentrantReadWriteLock之写锁加锁流程
写锁的加锁流程:
- 获取state值的低16位值
- 判断是否有线程持有锁资源
- 如果有线程持有读锁,返回false;或者有线程持有写锁,但是不是当前线程,返回false
- 否则,是当前线程持有写锁,进行重入锁流程
- 如果没有线程持有锁,判断当前线程竞争的是公平锁还是非公平锁
- 如果是公平锁,加入同步队列挂起;如果是非公平锁,竞争一波锁资源
public void lock() {
sync.acquire(1);
}
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
protected final boolean tryAcquire(int acquires) {
// 获取当前线程
Thread current = Thread.currentThread();
// 获取state值
int c = getState();
// 获取state低16位值
int w = exclusiveCount(c);
// 判断是否有线程获得锁
if (c != 0) {
// 有线程获得锁
// 判断是否有线程获得写锁
// 或者获得写锁的线程是否是当前线程
if (w == 0 || current != getExclusiveOwnerThread())
// 获得写锁的线程不是当前线程
return false;
// 当前线程获得写锁
// 判断写锁重入次数是否达到上限
if (w + exclusiveCount(acquires) > MAX_COUNT)
throw new Error("Maximum lock count exceeded");
// 写锁重入次数没有达到上限
// 追加锁重入次数
setState(c + acquires);
return true;
}
// 没有线程获得锁
// writerShouldBlock方法判断线程是否应该挂起,非公平锁返回false
// 公平锁判断AQS中是否有线程排队,如果有,head的next节点是否是当前线程,如果是,返回false
// 非公平锁的情况下判断是否获得锁
if (writerShouldBlock() ||
!compareAndSetState(c, c + acquires))
// 没有获得锁
return false;
// 获得锁
setExclusiveOwnerThread(current);
return true;
}