Java并发系列 | AbstractQueuedSynchronizer源码分析之共享模式
发布日期:2021-05-19 16:45:04 浏览次数:20 分类:精选文章

本文共 1297 字,大约阅读时间需要 4 分钟。

AbstractQueuedSynchronizer共享模式分析

通过对AbstractQueuedSynchronizer源码的深入分析,我们得知共享模式下获取锁的方式与独占模式高度相似,主要有以下三种获取锁的方式:不响应线程中断的获取、响应线程中断的获取以及设置超时时间的获取。熟悉这些方式后,之后对源码的阅读会显得异常熟练。

一、不响应线程中断的获取

共享模式下的acquireShared方法采用不响应线程中断的方式获取锁。首先通过tryAcquireShared方法尝试获取锁,这个方法返回值的判断规则如下:

  • 返回值小于0:表示当前结点获取锁失败,进而调用doAcquireShared方法将当前线程加入同步队列。
  • 返回值为0:表示当前结点获取成功,但后继结点无权限继续获取。
  • 返回值大于0:表示当前结点获取成功,且后继结点可以继续获取锁。
实现细节:
  • doAcquireShared方法的主要逻辑为:

    • 将当前线程加入同步队列。
    • 不断循环检查前驱结点是否为head结点。
    • 如果前驱结点为head结点,尝试调用tryAcquireShared获取锁。
    • 根据返回状态决定是否唤醒后继结点,并更新锁状态。
    • 在阻塞状态下,判断是否需要将线程挂起。
  • setHeadAndPropagate方法负责锁的状态传播:

    • 更新head结点。
    • 根据传入状态决定是否唤醒后继结点。
    • 更新下一个结点的状态。
  • 二、响应线程中断的获取

    响应线程中断的获取流程与不响应线程中断的方式基本类似,但主要区别在于中断处理的位置。acquireSharedInterruptibly方法首先检查线程中断状态,如果中断则抛出InterruptedException异常。接着调用doAcquireSharedInterruptibly方法,逻辑上与doAcquireShared方法一致。

    实现细节:
    • 在阻塞状态下,线程会被立即响应中断并抛出异常。

    三、设置超时时间的获取

    共享模式下的tryAcquireSharedNanos方法允许 caller设定获取锁的超时时间。逻辑上与doAcquireSharedNanos方法为核心:

  • 线程在超时内循环调用tryAcquireShared获取锁。
  • 如果超时未到,线程被挂起一定时间。
  • 超时到时,如果未成功获取锁,结束获取并返回失败状态。
  • 关键点:
    • 超时控制通过LockSupport.parkNanos实现。
    • 每次获取锁时间从超时中扣除。

    四、共享模式下结点的出队操作

    线程释放锁时,先调用tryReleaseShared方法:

    • 如果释放成功,调用doReleaseShared唤醒后继结点。
    • 如果释放失败,仅返回失败状态。
    详细步骤:
  • doReleaseShared方法不断迭代检查head结点的状态。
  • 根据头节点的等待状态决定是否唤醒后继结点。
  • 头节点状态更新为0PROPAGATE,根据后继节点是否存在。
  • 通过对以上关键点的理解,读者将能够从根本上掌握共享模式的实现原理。这篇文章详细介绍了共享模式的获取方式(包含三种方式)和释放方式,读者可以结合自身需求进行深入研究。

    上一篇:Java并发系列 | AbstractQueuedSynchronizer源码分析之独占模式
    下一篇:redis,学会这8点

    发表评论

    最新留言

    第一次来,支持一个
    [***.219.124.196]2025年05月12日 14时55分10秒

    关于作者

        喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
    -- 愿君每日到此一游!

    推荐文章

    Kubernetes学习总结(2)——Kubernetes设计架构 2025-04-03
    Kubernetes学习总结(3)——一年时间打造全球最大规模之一的Kubernetes集群,蚂蚁金服怎么做到的? 2025-04-03
    Kubernetes学习总结(4)——Kubernetes v1.20 重磅发布 | 新版本核心主题 & 主要变化解读 2025-04-03
    Kubernetes学习总结(5)——Kubernetes 常见面试题汇总 2025-04-03
    Kubernetes学习总结(6)——Kubernetes 7周年:它为什么如此受欢迎? 2025-04-03
    Kubernetes学习总结(7)——学习 Kubernetes 的 Pod 2025-04-03
    Kubernetes学习总结(8)—— Kubernetes Pod 资源管理 和 Pod 服务质量 2025-04-03
    Kubernetes学习总结(9)—— 基础架构的未来是 K8s,那么 K8s 的未来在何方? 2025-04-03
    kubernetes实战(十三):k8s使用helm持久化部署harbor集成openLDAP登录 2025-04-03
    Kubernetes实战(一)-Kubernetes集群搭建 2025-04-03
    Kubernetes实战(七)-优先级调度(Pod Priority Preemption) 2025-04-03
    Kubernetes实战(三十一)-Calico网络部署(推荐) 2025-04-03
    Kubernetes实战(三十三)-外部Etcd集群部署与调优(更安全的数据存储策略) 2025-04-03
    Kubernetes实战(三十二)-Kubeadm 安装 Kubernetes v1.24.0 2025-04-03
    Kubernetes实战(三)-定向调度(NodeSelector) 2025-04-03
    Kubernetes实战(二十九)-集群资源管理(CPU & Memory) 2025-04-03
    Kubernetes实战(二十二)-Etcd 集群部署(安全) 2025-04-03
    Kubernetes实战(二十五)-Flannel 网络部署(不推荐,不支持 Etcd3) 2025-04-03
    Kubernetes实战(二十八)-环境共享与隔离(Namespace) 2025-04-03
    Kubernetes实战(二十四)-kubernetes二进制文件方式部署集群(安全)(下) 2025-04-03