多线程与高并发(四)--ReentrantLock及AQS源码

ReentrantLock源码

 

 父子类关系:NonfairSync->Sync->AQS

AQS源码

  核心是volatile int state以及等待队列。

  • state的具体含义交给子类来定义。
    • ReentrantLock中state代表加解锁。
    • CountDownLatch中state代表需要countDown几次。
  • 内部维护了一个内部类Node(存放Thread),由Node组成了一个Thread的双向链表(等待队列)。获取到锁就移出等待队列,等待锁的释放就进入等待队列。
    • PS:入队出队操作为CAS
    • 入队代码

      private Node addWaiter(Node mode) {
              Node node = new Node(Thread.currentThread(), mode);
              // Try the fast path of enq; backup to full enq on failure
              Node pred = tail; // 尾插法
              if (pred != null) {
                  node.prev = pred;
                  // 使用CAS入队
                  if (compareAndSetTail(pred, node)) {
                      pred.next = node;
                      return node;
                  }
              }
              enq(node);
              return node;
          }
      
          private Node enq(final Node node) {
              for (;;) {
                  Node t = tail;
                  if (t == null) { // Must initialize
                      if (compareAndSetHead(new Node()))
                          tail = head;
                  } else {
                      node.prev = t;
                      if (compareAndSetTail(t, node)) {
                          t.next = node;
                          return t;
                      }
                  }
              }
          }

       

    • 第二个节点争用到锁将会被设置为新的头结点

      final boolean acquireQueued(final Node node, int arg) {
              boolean failed = true;
              try {
                  boolean interrupted = false;
                  for (;;) {
                      final Node p = node.predecessor();
                      // 如果前置节点是头结点并且当前节点成功争用到锁
                      if (p == head && tryAcquire(arg)) {
                          setHead(node);
                          p.next = null; // help GC
                          failed = false;
                          return interrupted;
                      }
                      // 其余情况处于阻塞状态
                      if (shouldParkAfterFailedAcquire(p, node) &&
                              parkAndCheckInterrupt())
                          interrupted = true;
                  }
              } finally {
                  if (failed)
                      cancelAcquire(node);
              }
          }

 

posted @ 2021-02-14 11:24  January01  阅读(42)  评论(0)    收藏  举报