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

     更新时间:2019年03月13日 15:51:13   作者?#21495;?#34382;。。   我要评论

    这篇文章主要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,否则判?#31995;?#21069;线程是否为exclusiveOwnerThread,然后把state++,也就是重入锁的体现,我们注意前半部分是通过CAS来保证同步,后半部分并没有同步的体现,原因是:后半部分是线程重入,再?#20301;?#24471;锁时才触发的操作,此时当前线程拥有锁,所以对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 是共享锁。
    ?#26085;?#21040;等待队列的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()的用法详解整合,希望对大家有所帮助,如果大家有任?#25105;?#38382;请给我留言,小编会及时回复大家的。在此也非常?#34892;?#22823;家对脚本之家网站的支持!

    您可能?#34892;?#36259;的文章:

    相关文章

    • Spring MVC 中 AJAX请求并返回JSON的示例

      Spring MVC 中 AJAX请求并返回JSON的示例

      本篇文章主要介绍了Spring MVC 中 AJAX请求并返回JSON,具有一定的参考价值,有兴趣的可以了解一下。
      2017-01-01
    • java获取ip地址与网络接口的方法示例

      java获取ip地址与网络接口的方法示例

      这篇文章主要给大家介绍了关于利用java如?#20301;?#21462;ip地址与网络接口的相关资?#24076;?#25991;中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
      2018-01-01
    • Java数据结构与算法之选择?#21028;?动力节点java学院整理)

      Java数据结构与算法之选择?#21028;?动力节点java学院整理)

      这篇文章主要介绍了Java数据结构与算法之选择?#21028;?#30340;相关资?#24076;?#26412;文通过代码讲解,非常不错,具有参考借鉴价值,需要的的朋友参考下
      2017-04-04
    • java随机抽取指定范围不重复的数字

      java随机抽取指定范围不重复的数字

      这篇文章主要介绍了java随机抽取指定范围不重复的数字的相关资料,需要的朋友可以参考下
      2016-06-06
    • Kotlin 基本语法实例详解

      Kotlin 基本语法实例详解

      这篇文章主要介绍了Kotlin 基本语法实例详解的相关资料,需要的朋友可以参考下
      2017-06-06
    • JAVA时间日期处理类实例

      JAVA时间日期处理类实例

      这篇文章主要介绍了JAVA时间日期处理类,可实现遍历两个日期之间的每一天的功能,涉及针对日期的常见操作技巧,需要的朋友可以参考下
      2015-04-04
    • MyBatis中如何优雅的使用枚举详解

      MyBatis中如何优雅的使用枚举详解

      枚举类型是我们在开发中经常遇到的一个类型,最近在学习MyBatis,但是发现网上没有详细介绍MyBatis如何使用枚举的相关文章,索性就自己写一篇,下面这篇文章主要给大家介绍了关于在MyBatis中如何优雅的使用枚举的相关资?#24076;?#38656;要的朋友可以参考借鉴。
      2017-08-08
    • Springboot网站第三方登录 微信登录

      Springboot网站第三方登录 微信登录

      这篇文章主要为大家详细介绍了Springboot网站第三方登录 ,微信登录,具有一定的参考价值,?#34892;?#36259;的小伙伴们可以参?#23478;?#19979;
      2017-12-12
    • WebSocket实现Web聊天室功能

      WebSocket实现Web聊天室功能

      这篇文章主要为大家详细介绍了WebSocket实现Web聊天室功能,具有一定的参考价值,?#34892;?#36259;的小伙伴们可以参?#23478;?#19979;
      2018-08-08
    • java中List对象?#21028;?#36890;用方法

      java中List对象?#21028;?#36890;用方法

      这篇文章主要介绍了java中List对象?#21028;?#36890;用方法,涉及java针对List对象的操作技巧,需要的朋友可以参考下
      2015-05-05

    最新评论

    山东群英会开奖查询