protected final boolean tryAcquire(int acquires) { Thread current = Thread.currentThread();monitor int c = getState(); // 重入锁的计数 int w = exclusiveCount(c); // 计数高低位拆开为读计数跟写计数,计算写计数 if (c != 0) { // 有人在占有锁 if (w == 0 || current != getExclusiveOwnerThread()) // 写计数为0,只有读锁直接返回(避免了读锁升级为写锁) 或者 当前线程不是执行线程(执行线程可能读也可能写)也返回 return false; if (w + exclusiveCount(acquires) > MAX_COUNT) //写锁重入次数 > 65525,抛出异常 throw new Error("Maximum lock count exceeded"); setState(c + acquires); //重入的写线程,直接设置状态(第6行代码没有return,说明当前线程是重入的写线程(写计数不是0,且current就是获取锁的线程)) return true; } if (writerShouldBlock() || !compareAndSetState(c, c + acquires)) //c!=0没有return,说明当前锁是空着的,因此cas抢占 return false; setExclusiveOwnerThread(current); // 当前线程参数设置 return true; }
public final void acquire(int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) //没有获取到,就往等待队列添加节点,而后挂起线程 selfInterrupt(); }
protected final boolean tryRelease(int releases) { if (!isHeldExclusively()) //没有写锁,抛异常 throw new IllegalMonitorStateException(); int nextc = getState() - releases; boolean free = exclusiveCount(nextc) == 0; //次数是否清0了 if (free) //清0 了,说明彻底释放了 setExclusiveOwnerThread(null); setState(nextc); return free; }
protected final int tryAcquireShared(int unused) { Thread current = Thread.currentThread(); int c = getState(); if (exclusiveCount(c) != 0 && getExclusiveOwnerThread() != current) // 有写锁 且当前线程不是写锁线程,不能重入,失败 return -1; int r = sharedCount(c); //向右移位,获取读锁计数 if (!readerShouldBlock() && r < MAX_COUNT && compareAndSetState(c, c + SHARED_UNIT)) { // 若无需排队 && 读计数<65535(16位最大值) && 状态设置成功(读锁的总体计数就是在这里改的,注意加了一个默认值的操做) if (r == 0) { //读锁为0 firstReader = current; //记录第一个获取锁的线程 firstReaderHoldCount = 1; } else if (firstReader == current) { //是本身重入的 firstReaderHoldCount++; } else { // HoldCounter rh = cachedHoldCounter; //用于计算读计数的计数器 if (rh == null || rh.tid != getThreadId(current)) cachedHoldCounter = rh = readHolds.get(); else if (rh.count == 0) readHolds.set(rh); rh.count++; //当前线程的读计数+1 } return 1; } return fullTryAcquireShared(current); //第7行条件不知足,则for循环获取读锁(实际不会死循环的) }
final int fullTryAcquireShared(Thread current) { HoldCounter rh = null; for (;;) { int c = getState(); if (exclusiveCount(c) != 0) { // 有写锁 if (getExclusiveOwnerThread() != current) // 写锁持有者不是当前线程,获取失败,经过aqs的doAcquireShared()进入排队 return -1; //这里只作了不是当前线程的判断,若是是当前线程,这个地方不能进行排队,由于若已有写线程在排队的话,就会形成死锁,源码中else一句的英文备注就是说这个 } else if (readerShouldBlock()) { //没写锁,但可能有写锁在等待读锁释放!!须要排队 // 写锁空闲 且 公平策略决定 线程应当被阻塞 // 下面的处理是说,若是是已获取读锁的线程重入读锁时, 即便公平策略指示应当阻塞也不会阻塞。 // 不然,这也会致使死锁的。 if (firstReader == current) { // // assert firstReaderHoldCount > 0; } else { // threadlocal 相关处理 if (rh.count == 0) // 须要阻塞且是非重入(还未获取读锁的),获取失败 return -1; } } if (sharedCount(c) == MAX_COUNT) throw new Error("Maximum lock count exceeded"); if (compareAndSetState(c, c + SHARED_UNIT)) { // cas 抢锁成功 //threadlocal相关处理 return 1; } } }
protected final boolean tryReleaseShared(int unused) { Thread current = Thread.currentThread(); if (firstReader == current) {// 清理firstReader缓存 或 readHolds里的重入计数 // assert firstReaderHoldCount > 0; if (firstReaderHoldCount == 1) firstReader = null; else firstReaderHoldCount--; } 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)) // 释放读锁对其余读线程没有任何影响, // 但能够容许等待的写线程继续,若是读锁、写锁都空闲。 return nextc == 0; } }
if (exclusiveCount(c) != 0) { if (getExclusiveOwnerThread() != current) return -1;
public void processCachedData() { readLock.lock(); if(!update){ //必须先释放读锁 readLock.unlock(); //锁降级从写锁获取到开始 writeLock.lock(); try{ if(!update){ //准备数据的流程(略) update = true; } readLock.lock(); }finally { writeLock.unlock(); } //锁降级完成,写锁降级为读锁 } try{ //使用数据的流程 }finally { readLock.unlock(); } }