gpt4 book ai didi

详解tryAcquire()、addWaiter()、acquireQueued()

转载 作者:qq735679552 更新时间:2022-09-29 22:32:09 24 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章详解tryAcquire()、addWaiter()、acquireQueued()由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

本文实例为大家分享了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()的用法详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我网站的支持! 。

最后此篇关于详解tryAcquire()、addWaiter()、acquireQueued()的文章就讲到这里了,如果你想了解更多关于详解tryAcquire()、addWaiter()、acquireQueued()的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com