AbstractQueuedSynchronizer 原理解析(下)

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: AbstractQueuedSynchronizer 原理解析

Semaphore


image.png


深入理解


  • 锁, 面向锁的使用者, 核心是定义了程序和锁的交互 API


  • 同步器,面向锁的实现者, 比如 Java 并发大神 Doug Lee , 提出同一规范并且简化了锁的实现,屏蔽了同步状态管理、阻塞线程排队和通知、唤醒机制等。


AQS 作用


加锁会导致阻塞


有阻塞就需要排队,实现排队必然需要某种形式的队列来进行管理。


解释说明


抢到资源的线程直接使用处理业务逻辑,抢不到资源的必然进入一种排队等候机制。抢占资源失败的线程去等待(类似银行业务遍历窗口都满了,暂时没有受理窗口的顾客只能去候客区排队等候),但等待线程仍然保持获取锁的可能且获取锁流程仍在继续(候客区的顾客也在等待着叫号,轮到了再去受理窗口办理业务)。


既然提到了排队等候机制。 那么就一定会有某种队列形成,这样的队列是什么数据结构呢?


如果共享资源被占用,就需要一定的阻塞等待唤醒机制来保证锁的分配。这个机制主要是通过 CHL 队列的变体来实现的,将暂时获取不到的锁的线程加入到队列中,这个队列就是 AQS 的抽象实现。它将请求共享资源的线程封装成队列的节点 Node , 通过 CAS , 自旋以及 LockSupport.park() 的方式,维护 sate 变量的状态,使并发达到同步的控制效果。


image.png


AQS 实践


AQS 初步认识


image.png


有阻塞就需要有排队,实现排队必须需要队列


AQS 使用一个 volatile 的 int 类型的成员变量来表示同步状态,通过内置的 FIFO 队列来完成资源获取的排队工作将每条要去抢占资源的线程封装成一个 Node 节点来实现锁的分配,通过 CAS 完成对 State 值的修改。


image.png


AQS 内部体系架构


image.png


AQS 组成


  • AQS 的 int 变量


AQS 同步状态 State 成员变量


/**
     * The synchronization state.
     */
    private volatile int state;


银行办理业务的受理窗口状态


1、0 就是没人, 自由状态可以办理


2、大于等于 1 , 有人占用窗口,等着去


  • AQS 的 CLH 队列


CLH 队列(三个大牛的名字组成),为一个双向队列


image.png


银行候客区的等待顾客


  • 小总结


有阻塞就需要排队,实现排队必然需要队列


state + CLH 变种的双端队列


AQS 同步队列的基本结构


  • Node 中的 int 变量


Node 的等待状态 waitState 成员变量


volatile int waitStatus;


总结一下


等候区其他顾客(其他线程)的等待状态


队列中每个排队的个体就是一个 Node


  • Node 类的详解


static final class Node {
    // 共享
        static final Node SHARED = new Node();
        // 独占
        static final Node EXCLUSIVE = null;
    // 线程被取消了
        static final int CANCELLED =  1;
    // 后继线程需要唤醒
        static final int SIGNAL    = -1;
    // 等待 condition 唤醒
        static final int CONDITION = -2;
    // 共享式同步状态获取将会无条件的传播下去
        static final int PROPAGATE = -3;
        // 初始状态为 0 , 状态式上面的几种
        volatile int waitStatus;
        // 前置节点
        volatile Node prev;
        // 后置节点
        volatile Node next;
        // 当前线程
        volatile Thread thread;
        Node nextWaiter;
        final boolean isShared() {
            return nextWaiter == SHARED;
        }
        final Node predecessor() throws NullPointerException {
            Node p = prev;
            if (p == null)
                throw new NullPointerException();
            else
                return p;
        }
        Node() {    // Used to establish initial head or SHARED marker
        }
        Node(Thread thread, Node mode) {     // Used by addWaiter
            this.nextWaiter = mode;
            this.thread = thread;
        }
        Node(Thread thread, int waitStatus) { // Used by Condition
            this.waitStatus = waitStatus;
            this.thread = thread;
        }
    }


AQS 同步队列的基本结构


image.png


相关文章
|
8天前
|
存储 缓存 算法
HashMap深度解析:从原理到实战
HashMap,作为Java集合框架中的一个核心组件,以其高效的键值对存储和检索机制,在软件开发中扮演着举足轻重的角色。作为一名资深的AI工程师,深入理解HashMap的原理、历史、业务场景以及实战应用,对于提升数据处理和算法实现的效率至关重要。本文将通过手绘结构图、流程图,结合Java代码示例,全方位解析HashMap,帮助读者从理论到实践全面掌握这一关键技术。
46 13
|
26天前
|
运维 持续交付 云计算
深入解析云计算中的微服务架构:原理、优势与实践
深入解析云计算中的微服务架构:原理、优势与实践
59 1
|
2天前
|
网络协议 安全 网络安全
探索网络模型与协议:从OSI到HTTPs的原理解析
OSI七层网络模型和TCP/IP四层模型是理解和设计计算机网络的框架。OSI模型包括物理层、数据链路层、网络层、传输层、会话层、表示层和应用层,而TCP/IP模型则简化为链路层、网络层、传输层和 HTTPS协议基于HTTP并通过TLS/SSL加密数据,确保安全传输。其连接过程涉及TCP三次握手、SSL证书验证、对称密钥交换等步骤,以保障通信的安全性和完整性。数字信封技术使用非对称加密和数字证书确保数据的机密性和身份认证。 浏览器通过Https访问网站的过程包括输入网址、DNS解析、建立TCP连接、发送HTTPS请求、接收响应、验证证书和解析网页内容等步骤,确保用户与服务器之间的安全通信。
17 1
|
1月前
|
运维 持续交付 虚拟化
深入解析Docker容器化技术的核心原理
深入解析Docker容器化技术的核心原理
47 1
|
27天前
|
存储 供应链 算法
深入解析区块链技术的核心原理与应用前景
深入解析区块链技术的核心原理与应用前景
52 0
|
1月前
|
算法 Java 数据库连接
Java连接池技术,从基础概念出发,解析了连接池的工作原理及其重要性
本文详细介绍了Java连接池技术,从基础概念出发,解析了连接池的工作原理及其重要性。连接池通过复用数据库连接,显著提升了应用的性能和稳定性。文章还展示了使用HikariCP连接池的示例代码,帮助读者更好地理解和应用这一技术。
59 1
|
1月前
|
JavaScript 前端开发 API
Vue.js响应式原理深度解析:从Vue 2到Vue 3的演进
Vue.js响应式原理深度解析:从Vue 2到Vue 3的演进
57 0
|
1月前
|
API 持续交付 网络架构
深入解析微服务架构:原理、优势与实践
深入解析微服务架构:原理、优势与实践
31 0
|
1月前
|
存储 供应链 物联网
深入解析区块链技术的核心原理与应用前景
深入解析区块链技术的核心原理与应用前景
|
1月前
|
存储 供应链 安全
深度解析区块链技术的核心原理与应用前景
深度解析区块链技术的核心原理与应用前景
43 0

推荐镜像

更多