面试官:说一下AQS共享/独占式获取/释放资源的区别

本文深入探讨了AQS(AbstractQueuedSynchronizer)的共享和独占模式下获取与释放资源的差异,包括acquire、acquireShared、release和releaseShared等关键方法的逻辑。在独占模式下,只有一个线程能获取资源,而共享模式允许多个线程同时获取。文章还分析了setHeadAndPropagate方法在共享模式释放资源时的角色,确保唤醒传播的正确性。
摘要由CSDN通过智能技术生成

介绍了AQS内置队列节点的出队入队操作,以及独占式获取共享资源与释放资源的详细流程,为了结构完整,本篇继续以AQS的角度介绍另外一种:共享模式获取与释放资源的细节,本篇暂不分析具体子类如ReentrantLock、ReentrantReadWriteLock的实现,之后会陆续补充。

独占式获取资源

友情提示:本篇文章着重介绍共享模式获取和释放资源的特点,许多代码实现上面和共享式和独占式其实逻辑差不多,为了清晰对比,这边会将独占式的部分核心代码粘贴过来,注意理解共享式和独占式存在差异的地方。详细解析可看我上一篇:Java并发包源码学习系列:CLH同步队列及同步资源获取与释放

void acquire(int arg)

public final void acquire(int arg) {        if (!tryAcquire(arg) && // tryAcquire由子类实现,表示获取锁,如果成功,这个方法直接返回了            acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) // 如果获取失败,执行            selfInterrupt();    }

boolean acquireQueued(Node, int)

// 这个方法如果返回true,代码将进入selfInterrupt()	final boolean acquireQueued(final Node node, int arg) {        // 注意默认为true        boolean failed = true;        try {            // 是否中断            boolean interrupted = false;            // 自旋,即死循环            for (;;) {                // 得到node的前驱节点                final Node p = node.predecessor();                // 我们知道head是虚拟的头节点,p==head表示如果node为阻塞队列的第一个真实节点                // 就执行tryAcquire逻辑,这里tryAcquire也需要由子类实现                if (p == head && tryAcquire(arg)) {                    // tryAcquire获取成功走到这,执行setHead出队操作                     setHead(node);                    p.next = null; // help GC                    failed = false;                    return interrupted;                }                // 走到这有两种情况 1.node不是第一个节点 2.tryAcquire争夺锁失败了                // 这里就判断 如果当前线程争锁失败,是否需要挂起当前这个线程                if (shouldParkAfterFailedAcquire(p, node) &&                    parkAndCheckInterrupt())                    interrupted = true;            }        } finally {            // 死循环退出,只有tryAcquire获取锁失败的时候failed才为true            if (failed)                cancelAcquire(node);        }    }

独占式释放资源

boolean release(int arg)

public final boolean release(int arg) {        if (tryRelease(arg)) { // 子类实现tryRelease方法            // 获得当前head            Node h = head;            // head不为null并且head的等待状态
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值