91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

tryAcquire()、addWaiter()、acquireQueued()三者的區別是什么

發布時間:2021-06-17 11:34:37 來源:億速云 閱讀:186 作者:Leah 欄目:編程語言

tryAcquire()、addWaiter()、acquireQueued()三者的區別是什么,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

tryAcquire()

final boolean nonfairTryAcquire(int acquires) {
      final Thread current = Thread.currentThread();
      int c = getState();
      if (c == 0) {
        if (compareAndSetState(0, acquires)) {
          setExclusiveOwnerThread(current);
          return true;
        }
      }
      else if (current == getExclusiveOwnerThread()) {
        int nextc = c + acquires;
        if (nextc < 0) // overflow
          throw new Error("Maximum lock count exceeded");
        setState(nextc);
        return true;
      }
      return false;
    }

先判斷state是否為0,如果為0就執行上面提到的lock方法的前半部分,通過CAS操作將state的值從0變為1,否則判斷當前線程是否為exclusiveOwnerThread,然后把state++,也就是重入鎖的體現,我們注意前半部分是通過CAS來保證同步,后半部分并沒有同步的體現,原因是:后半部分是線程重入,再次獲得鎖時才觸發的操作,此時當前線程擁有鎖,所以對ReentrantLock的屬性操作是無需加鎖的。如果tryAcquire()獲取失敗,則要執行addWaiter()向等待隊列中添加一個獨占模式的節點。

addWaiter()

/**
   * Creates and enqueues node for current thread and given mode.
   *
   * @param mode Node.EXCLUSIVE for exclusive, Node.SHARED for shared
   * @return the new node
   */
  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;
      if (compareAndSetTail(pred, node)) {
        pred.next = node;
        return node;
      }
    }
    enq(node);
    return node;
  }

這個方法的注釋:創建一個入隊node為當前線程,Node.EXCLUSIVE 是獨占鎖, Node.SHARED 是共享鎖。
先找到等待隊列的tail節點pred,如果pred!=null,就把當前線程添加到pred后面進入等待隊列,如果不存在tail節點執行enq()

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;
        }
      }
    }
  }

這里進行了循環,如果此時存在了tail就執行同上一步驟的添加隊尾操作,如果依然不存在,就把當前線程作為head結點。
插入節點后,調用acquireQueued()進行阻塞

acquireQueued()

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);
    }
  }

先獲取當前節點的前一節點p,如果p是head的話就再進行一次tryAcquire(arg)操作,如果成功就返回,否則就執行shouldParkAfterFailedAcquire、parkAndCheckInterrupt來達到阻塞效果;

關于tryAcquire()、addWaiter()、acquireQueued()三者的區別是什么問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

保亭| 海南省| 新疆| 闸北区| 永福县| 蓝山县| 万荣县| 鄄城县| 东兴市| 长武县| 读书| 邵东县| 昌邑市| 淄博市| 潼关县| 洪泽县| 将乐县| 凌云县| 剑川县| 吉木乃县| 大石桥市| 西峡县| 县级市| 湘西| 云龙县| 喀什市| 仁寿县| 湟源县| 自治县| 南川市| 穆棱市| 长子县| 五家渠市| 贵定县| 无棣县| 台南市| 兴宁市| 阿拉善盟| 哈密市| 临朐县| 会宁县|