国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > Java > 正文

詳解tryAcquire()、addWaiter()、acquireQueued()

2024-07-14 08:43:38
字體:
來源:轉載
供稿:網友

本文實例為大家分享了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()的用法詳解整合,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對VeVb武林網網站的支持!


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 启东市| 寿光市| 将乐县| 米林县| 玉环县| 汉中市| 乌兰察布市| 社旗县| 惠安县| 兰州市| 灵石县| 奇台县| 资兴市| 新乡县| 越西县| 枞阳县| 肥西县| 阳原县| 朝阳市| 福州市| 定兴县| 河北区| 云浮市| 张家口市| 叶城县| 河池市| 建湖县| 武功县| 大庆市| 奉节县| 留坝县| 阜城县| 太谷县| 高雄县| 乌审旗| 田东县| 桓仁| 汨罗市| 南涧| 峨眉山市| 磴口县|