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

作者:胖虎。。 时间:2022-07-30 10:24:05 

本文实例为大家分享了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()的用法详解整合网站的支持!

来源:https://blog.csdn.net/weixin_38003389/article/details/85935982

标签:tryAcquire,addWaiter,acquireQueued
0
投稿

猜你喜欢

  • Java实现简单的扫雷小程序

    2022-11-18 02:14:07
  • spring boot2结合mybatis增删改查的实现

    2023-07-07 01:17:31
  • java学生管理系统界面简单实现(全)

    2023-11-28 21:35:25
  • java 使用idea将工程打成jar并创建成exe文件类型执行的方法详解

    2022-12-07 02:49:30
  • Java使用iTextPDF生成PDF文件的实现方法

    2023-10-15 10:44:13
  • Java中 ? extends T 和 ? super T的理解

    2022-06-26 19:50:23
  • 解决nacos升级spring cloud 2020.0无法使用bootstrap.yml的问题

    2021-12-02 19:44:29
  • Spring MVC深入学习之启动初始化过程

    2023-07-16 07:04:21
  • ThreadLocal使用案例_动力节点Java学院整理

    2021-06-08 09:57:15
  • SpringMVC @RequestBody自动转json Http415错误的解决

    2022-09-12 13:12:34
  • Android 实现可任意拖动的悬浮窗功能(类似悬浮球)

    2023-08-07 10:19:05
  • java8 实现提取集合对象的每个属性

    2023-10-17 19:37:27
  • C语言 OutputDebugString与格式化输出函数OutputDebugPrintf案例详解

    2023-11-02 16:21:47
  • Spring使用@Autowired为抽象父类注入依赖代码实例

    2023-02-01 09:30:35
  • Flutter Widgets粘合剂CustomScrollView NestedScrollView滚动控件

    2023-07-06 01:24:29
  • java中ArrayList和LinkedList的区别详解

    2022-09-05 11:13:48
  • Java日常练习题,每天进步一点点(7)

    2023-11-27 00:34:58
  • java 使用foreach遍历集合元素的实例

    2022-11-17 09:24:58
  • java 多态性详解及常见面试题

    2023-03-15 18:08:49
  • 简单谈谈Java中的栈和堆

    2022-07-30 05:33:01
  • asp之家 软件编程 m.aspxhome.com