tryReleaseShared,尝试释放锁也就是改变state状态
protected final boolean tryReleaseShared(int unused) {//暂时不关心Thread current = Thread.currentThread();if (firstReader == current) {// assert firstReaderHoldCount > 0;if (firstReaderHoldCount == 1)firstReader = null;elsefirstReaderHoldCount--;} else {HoldCounter rh = cachedHoldCounter;if (rh == null || rh.tid != getThreadId(current))rh = readHolds.get();int count = rh.count;if (count <= 1) {readHolds.remove();if (count <= 0)throw unmatchedUnlockException();}--rh.count;}//开始释放读锁for (;;) {int c = getState();int nextc = c - SHARED_UNIT;if (compareAndSetState(c, nextc))// Releasing the read lock has no effect on readers,// but it may allow waiting writers to proceed if// both read and write locks are now free.return nextc == 0;}}
- int c = getState();获取state
- int nextc = c - SHARED_UNIT; 从高16位扣除掉读锁加锁次数;
- compareAndSetState(c, nextc) cas替换state变量
return nextc == 0; 读锁加锁次数都释放完了,nextc就是0,因此就返回true。如果没有释放完就得等外部在执行一次unlock操作了。
doReleaseShared,唤醒线程
private void doReleaseShared() {/** Ensure that a release propagates, even if there are other* in-progress acquires/releases. This proceeds in the usual* way of trying to unparkSuccessor of head if it needs* signal. But if it does not, status is set to PROPAGATE to* ensure that upon release, propagation continues.* Additionally, we must loop in case a new node is added* while we are doing this. Also, unlike other uses of* unparkSuccessor, we need to know if CAS to reset status* fails, if so rechecking.*/for (;;) {Node h = head;if (h != null && h != tail) {int ws = h.waitStatus;if (ws == Node.SIGNAL) {if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))continue; // loop to recheck casesunparkSuccessor(h);}else if (ws == 0 &&!compareAndSetWaitStatus(h, 0, Node.PROPAGATE))continue; // loop on failed CAS}if (h == head) // loop if head changedbreak;}}
Node h = head;

- ws == Node.SIGNAL;这一步肯定是要进去的。
- !compareAndSetWaitStatus(h, Node.SIGNAL, 0);这一步假设cas成功了,即便不成功因为有for循环还是能设置成功的

- unparkSuccessor(h);按队列顺序释放线程,这个是所有唤醒线程的公用方法。

