AQS的细节--自用,非正常教程

AQS的概念

AQS叫抽象队列同步器,是一个框架,我们可以在JUC很多包看见AQS的具体实现,比如锁和读写锁,condition等,具有可扩展性,可以根据此自定义同步工具类,优点是系统开销低,实现锁比较灵活,可扩展性强,满足特殊需求。

AQS的核心思想

AQS核心思想是,如果被请求的共享资源空闲,那么就将当前请求资源的线程设置为有效的工作线程,将共享资源设置为锁定状态如果共享资源被占用,就需要一定的阻塞等待唤醒机制来保证锁分配
这个机制主要用的是CLH队列的变体实现的,将暂时获取不到锁的线程加入到队列中。AQS使用一个Volatile修饰的int类型的成员变量(State)来表示同步状态,通过内置的FIFO队列来完成资源获取的排队工作,通过CAS完成对State值的修改。

AQS的数据结构

维护一个volatile修饰的int变量state,表示同步状态;
有一个节点类,一个节点用来表示一个线程,节点里面有双向指针,也有一个volatile修饰的int表示线程状态(waitStatus);
还有一个同步队列,说是队列,实际上是一个双向链表,逻辑上是队列,只能有一个;
最后有一个条件队列,它是一个单向链表,可以有多个。
Node节点数据结构:
在这里插入图片描述
·····················································································································
在这里插入图片描述

AQS同步状态

AQS中维护了一个名为state的字段,意为同步状态,是由Volatile修饰的,用于展示当前临界资源的获锁情况。
对于我们自定义的同步工具,需要自定义获取同步状态和释放状态的方式,也就是自定义获取state的值,和改变state值的方法。

AQS对各种锁的实现

重入锁实现原理

例如ReentrantLock中,state = 0,表示还没有线程获取锁,state = 1,说明正在被使用,state > 1,表示被重入了,说明ReentrantLock自定义了state等于xxx的时候,各自代表了什么意思。

公平锁与非公平锁原理

记住一点,获取锁成功与否的标志是此线程是否成功用CAS改变了state,使其改成锁被获取的状态(比如重入锁中state=1为成功获取锁,那么如果有一个线程将state改成1,代表此线程成功获取锁),成功了就算获取锁。等到state变成0,这个时候谁会去获取锁便成了个问题,如果我们这样设计:获取锁之前先判断锁是否被获取,如果被获取,此线程将乖乖排到队尾,这样就能实现公平锁,因为避免了插队的发生嘛;如果这样设计:不作判断直接CAS尝试获取锁,竞争成功就插队,这样能实现非公平锁,因为节点无视排序直接僭越想抢锁,此为非公平嘛。

独占模式实现原理

独占和共享模式是通过修改State字段表示的同步状态来实现的(比如state只能等于0,1,那就肯定是独占锁;如果state最大等于n,那么最多允许n个线程共享数据)
独占模式顾名思义,只能一个线程使用锁,加锁过程是:如果加锁失败就进入队列,加入队列的时候,为了避免前面的线程是被中断的,或者是发生异常的,那如果不处理这种线程,那这辈子此节点也获取不了锁,于是它利用pre指针访问前驱节点判断前驱节点的状态,不对的就删除,直到到达一个正常节点的背后;锁释放后,为了找到正常节点,也会将后继异常节点清除直到找到合适的来唤醒
在这里插入图片描述

共享模式实现原理

顾名思义,锁是可共享的,于是如果一个节点获取了锁,那么它将唤醒后续其他想获取锁的,节点状态是共享的所有节点,直到碰到非共享状态节点,解锁也会唤醒后续线程。

在这里插入图片描述

其他应用场景

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/329924.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mininet编程实现交换机规则的插入、删除与修改。_可编程网卡芯片在滴滴云网络的应用实践...

桔妹导读:随着云规模不断扩大以及业务层面对延迟、带宽的要求越来越高,采用DPDK 加速网络报文处理的方式在横向纵向扩展都出现了局限性。可编程芯片成为业界热点。本文主要讲述了可编程网卡芯片在滴滴云网络中的应用实践,遇到的问题、带来的收…

centos8上docker tomcat容器访问报404解决方法

目录 【README】 【1】docker安装tomcat 【2】启动多个tomcat容器 【README】 1.本文记录了 访问docker tomcat容器报404的解决方法; 2.附带安装tomcat步骤; 3.centos8 安装docker,refers2 centos8安装docker_PacosonSWJTU的博客-CSDN博…

ConcurrentHashMap--自用,非教学

结论先行,细节在下面 jdk1.7是如何解决并发问题的以及完整流程 一.首先new一个concurrentHashMap 调用默认构造方法 二.初始化 初始化initialCapacity(默认是16,指一个segment内Entry的数量),loadFactor&#xff…

Java开发必须掌握的线上问题排查命令

转载自 Java开发必须掌握的线上问题排查命令作为一个合格的开发人员,不仅要能写得一手还代码,还有一项很重要的技能就是排查问题。这里提到的排查问题不仅仅是在coding的过程中debug等,还包括的就是线上问题的排查。由于在生产环境中&#x…

centos8启动docker-mysql8容器

【README】 本文记录了 centos8 安装,启动mysql8的docker容器的步骤; 【1】安装mysql8 docker容器 步骤1, 查看mysql8 docker镜像版本 ; 最简单的方式是上 Docker Hubhttps://hub.docker.com/直接搜索mysql,查看其 …

Java命令学习系列(一)——Jps

转载自 Java命令学习系列(一)——Jpsjps位于jdk的bin目录下,其作用是显示当前系统的java进程情况,及其id号。 jps相当于Solaris进程工具ps。不象"pgrep java"或"ps -ef grep java",jps并不使用应用…

springboot2.5.5配置druid数据源1.2.8与jdbc

【README】 本文记录了 springboot配置 druid数据源的步骤; 【1】新建springboot项目并配置druid 步骤1,新建springbt项目 步骤2,选择spring web,jdbc,mysql驱动依赖; 步骤3,添加 druid数据源…

tsc244标签编辑软件_能打小票的标签机,M110智能标签打印机来了!

每张被贴上的标签背后,都是对待梦想的认真、对待生活的用心,M110智能标签打印机为你标记美好,实现品质与效率兼得的追求。01、 产品简介M110智能标签打印机采取热敏无墨打印技术,无需碳带,便捷经济,配套“标…

面试官:简述实现一个线程池的设计思路

前言 二面碰到这个问题人都麻了,我扯了好多没用的,面后赶紧来补一下,但是找到的基本都是一堆纯代码,不是讲思路的。下面的思路是我参考美团技术团队文章后总结的。 具体思路 一、总体设计 线程池在内部实际上构建了一个生产者…

Java命令学习系列(四)——jstat

转载自 Java命令学习系列(四)——jstatjstat(JVM Statistics Monitoring Tool)是用于监控虚拟机各种运行状态信息的命令行工具。他可以显示本地或远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据,在没有GUI图形的服务器上&…

修改打印机ip工具_使用富士施乐一体机因动态IP导致不能打印与扫描的解决方法...

背景在使用富士施乐的一体机中(其他厂商的一体机 也类似),很多人的网络环境是动态IP的,即打印的IP地址是不固定的,随着每次开机或关机会变化,从而经常有人反应打印机不能打印或者扫描了。。总体思路1. 检查当前的IP设置2. 把相应的…

springboot2.5.5配置mybatis

【README】 1.本文记录了 springboot2.5.5 配置 mybatis的步骤; 2.配置mybatis 分为注解和配置两种方式; 3.引入mybatis,包括了 创建springbt项目;druid数据源配置;数据库表与javabean;mybatis配置与sq…

Java命令学习系列(三)——Jmap

转载自 Java命令学习系列(三)——Jmapjmap是JDK自带的工具软件,主要用于打印指定Java进程(或核心文件、远程调试服务器)的共享对象内存映射或堆内存细节。可以使用jmap生成Heap Dump。在Java命令学习系列(零)——常见命…

skimage直方图如何保存_LightGBM的参数详解以及如何调优

lightGBM可以用来解决大多数表格数据问题的算法。有很多很棒的功能,并且在kaggle这种该数据比赛中会经常使用。但我一直对了解哪些参数对性能的影响最大以及我应该如何调优lightGBM参数以最大限度地利用它很感兴趣。我想我应该做一些研究,了解更多关于li…

基于springboot2.5.5自建启动器starter制品库

【README】 本文po出了自建springboot 启动器步骤; 【1】新建2个starter相关组件 根据 mybatis-spring-boot-starter,我们看到 自建starter需要两个组件,分别是 xxx-spring-boot-starter, xxx-spring-boot-starter-autoconfigu…

Java命令学习系列(二)——Jstack

转载自 Java命令学习系列(二)——Jstackjstack是java虚拟机自带的一种堆栈跟踪工具。功能 jstack用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出…

python中ls是什么_使用Python代码实现Linux中的ls遍历目录命令的实例代码

一、写在前面 前几天在微信上看到这样一篇文章,链接为:https://www.jb51.net/it/692145.html,在这篇文章中,有这样一段话,吸引了我的注意:在 Linux 中 ls 是一个使用频率非常高的命令了,可选的参…

spring中stereotype注解Component,Repository,Service,Controller

【README】 本文介绍了 spring4.0 下 org.springframework.stereotype 的注解类型,俗称刻板型注解(一成不变型); 包括 Component, Repository,Service, Controller ; 目录 【REA…

[中级]Java命令学习系列(五)——jhat

转载自 [中级]Java命令学习系列(五)——jhatjhat(Java Heap Analysis Tool),是一个用来分析java的堆情况的命令。之前的文章讲到过,使用jmap可以生成Java堆的Dump文件。生成dump文件之后就可以用jhat命令,将dump文件转成html的形式…

转:IDEA 创建类注释模板和方法注释模板

转自: IDEA 创建类注释模板和方法注释模板 - 简书  在使用Idea的时候,它的注释模板很简单,不够详细;所有大多数开发者都想设置一个比较详细的注释模板,我现在把我了解的创建类注释模板和方法注释模板的操作记录下来…