image.png

tryRelease,尝试释放锁

  1. protected final boolean tryRelease(int releases) {
  2. if (!isHeldExclusively())
  3. throw new IllegalMonitorStateException();
  4. int nextc = getState() - releases;
  5. boolean free = exclusiveCount(nextc) == 0;
  6. if (free)
  7. setExclusiveOwnerThread(null);
  8. setState(nextc);
  9. return free;
  10. }
  1. !isHeldExclusively();判断持有独占锁的线程是不是当前释放锁的线程,如果不是就要抛异常

image.png

  1. int nextc = getState() - releases;将state变量减一
  2. boolean free = exclusiveCount(nextc) == 0;通过获取state的第十六位看一下是否还是有写锁的标记,减一完是不是已经把所有所释放了,如果不等于0就返回false下边if判断就进不去。
  3. if (free)如果free==true就代表写锁都释放完毕了,就要把线程标记设置为null。同时返回free=true;

    释放写锁成功开始唤醒线程

    image.png
    由于释放写锁成功了,那么tryRelease就会返回true。

  4. Node h = head;拿到头节点

  5. h != null && h.waitStatus != 0;h != null代表有线程在队列中等待,同时判断一下watisStatus只有!=0了意味着线程才能被唤醒(规定)。
  6. unparkSuccessor(h);唤醒线程(AQS同一套的唤醒线程的方法)