国产探花免费观看_亚洲丰满少妇自慰呻吟_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教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 马尔康县| 方城县| 梧州市| 鄂伦春自治旗| 冷水江市| 乾安县| 乃东县| 通渭县| 涿州市| 和静县| 阜康市| 尤溪县| 射阳县| 麦盖提县| 彰化县| 禹城市| 张家口市| 新乐市| 仁化县| 怀柔区| 新野县| 天门市| 大埔县| 双流县| 黄大仙区| 阜南县| 新乡县| 固原市| 新龙县| 北海市| 行唐县| 浦县| 刚察县| 托克托县| 平陆县| 漯河市| 岳池县| 元谋县| 花莲市| 永嘉县| 金寨县|