读写锁:允许同一时刻被多个读线程访问,但是在写线程访问时,所有的读线程与其他的写线程均会阻塞。
写线程能够获取到锁的前提条件:没有任何读、写线程拿到锁。
1. 写锁-WriteLock-独占锁
1.1 写锁的获取 - 模板方法tryAcquire()
源码:
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);
if (c != 0) {
// (Note: if c != 0 and w == 0 then shared count != 0)
if (w == 0 || current != getExclusiveOwnerThread())
return false;
if (w + exclusiveCount(acquires) > MAX_COUNT)
throw new Error("Maximum lock count exceeded");
// Reentrant acquire
setState(c + acquires);
return true;
}
if (writerShouldBlock() ||
!compareAndSetState(c, c + acquires))
return false;
//获取写锁成功
setExclusiveOwnerThread(current);
return true;
}
c只是一个整型,那它到底表示的是读锁还是写锁?
我们通过读源码可以发现,同步状态的低16位表示写锁获取次数,高16位表示读锁获取次数。
写锁的获取逻辑:
当读锁已被线程获取或者写锁已被其他线程获取,则写线程获取锁失败;
否则,当前同步状态没有被任何读写线程获取,则当前线程获取写锁成功并且支持重入。
1.2 写锁的释放
写锁的释放逻辑与独占式锁的释放(release)逻辑一样:https://mp.youkuaiyun.com/mdeditor/87895586#