AQS(释放资源 4)--队列同步器

1.unparkSuccessor(Node)

   该方法主要用于唤醒等待队列中的下一个阻塞线程。

    private void unparkSuccessor(Node node) {

             // 获取当前节点的ws值

            int ws = node.waitStatus;

            // 将当前节点的ws值置0

            if (ws < 0)

                  compareAndSetWaitStatus(node, ws, 0);

                  Node s = node.next;

            // 若后继节点为null或者其ws值大于0(放弃状态),则从等待队列的尾节点从后往前搜索,

            // 搜索到等待队列中最靠前的ws值非正且非null的节点

           if (s == null || s.waitStatus > 0) {

                  s = null;

                  for (Node t = tail; t != null && t != node; t = t.prev)

                         if (t.waitStatus <= 0) s = t;

            }

            // 如果后继节点非null,则唤醒该后继节点持有的线程

            if (s != null)

                LockSupport.unpark(s.thread);

            }

          后继节点的阻塞线程被唤醒后,就进入到acquireQueued()的

          if (p == head && tryAcquire(arg))的判断中,

          此时被唤醒的线程将尝试获取资源。

          当然,如果被唤醒的线程所在节点的前继节点不是头结点,

           经过shouldParkAfterFailedAcquire的调整,

           也会移动到等待队列的前面,直到其前继节点为头结点。

            讲解完独占模式下资源的acquire/release过程,下面开始讲解共享模式下,

            线程如何完成资源的获取和共享。

 

学习来源:https://www.jianshu.com/p/0f876ead2846

posted @ 2020-09-01 15:44  小窝蜗  阅读(234)  评论(0)    收藏  举报