设为首页 加入收藏

TOP

10分钟从源码级别搞懂AQS(AbstractQueuedSynchronizer)(二)
2023-09-09 10:25:55 】 浏览:144
Tags:10分 钟从源 别搞懂 AQS AbstractQueuedSynchronizer
tail;        if (pred != null) {            node.prev = pred;            if (compareAndSetTail(pred, node)) {                pred.next = node;                return node;           }       }        //尾节点为空或则CAS失败执行enq        enq(node);        return node;   }
    private Node enq(final Node node) {
        //失败重试
        for (;;) {
            Node t = tail;
            //没有尾节点 则CAS设置头节点(头尾节点为一个节点),否则CAS设置尾节点
            if (t == null) { // Must initialize
                if (compareAndSetHead(new Node()))
                    tail = head;
            } else {
                node.prev = t;
                if (compareAndSetTail(t, node)) {
                    t.next = node;
                    return t;
                }
            }
        }
    }

enq方法主要以自旋(中途不会进入等待模式)去CAS设置尾节点,如果AQS中没有节点则头尾节点为同一节点

由于添加到尾节点存在竞争,因此需要用CAS去替换尾节点

image.png

acquireQueued

acquireQueued方法主要用于AQS队列中的节点来自旋获取同步状态,在这个自旋中并不是一直执行的,而是会被park进入等待

final boolean acquireQueued(final Node node, int arg) {
    //记录是否失败
    boolean failed = true;
    try {
        //记录是否中断过
        boolean interrupted = false;
        //失败重试 
        for (;;) {
            //p 前驱节点
            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 == head && tryAcquire(arg):前驱节点是头节点

因此AQS中的节点获取状态是FIFO的

但即使满足前驱节点是头节点,并不一定就能获取同步状态成功,因为还未加入AQS的线程也可能尝试获取同步状态,以此来实现非公平锁

那如何实现公平锁呢?

在尝试获取同步状态前都加上这个条件就行了呗!

再来看看

首页 上一页 1 2 3 4 5 6 7 下一页 尾页 2/7/7
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Nacos 注册中心的设计原理:让你.. 下一篇电商类面试问题--01Elasticsearch..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目