AQS

1

AQS抽象的队列同步器,AQS定义了一套多线程访问共享资源的同步器框架,许多同步类实现都依赖于它,如常用的ReentrantLock/Semaphore/CountDownLatch
在这里插入图片描述首先AQS维护了一个volatile 修饰的state和一个FIFO的同步队列(多线程争用资源被阻塞时会进入此队列),state的作用主要是用来表示当前锁的一个状态。这里volatile是核心关键词,具体volatile的语义,在此不述。state的访问方式有三种:

getState()	//	获得state
setState()	//设置state
compareAndSetState()	//cas自旋设置state

AQS定义两种资源共享方式:Exclusive(独占,只有一个线程能执行,如ReentrantLock)和Share(共享,多个线程可同时执行,如Semaphore/CountDownLatch)。
  不同的自定义同步器争用共享资源的方式也不同。自定义同步器在实现时只需要实现共享资源state的获取与释放方式即可,至于具体线程等待队列的维护(如获取资源失败入队/唤醒出队等),AQS已经在顶层实现好了。自定义同步器实现时主要实现以下几种方法:

isHeldExclusively():该线程是否正在独占资源。只有用到condition才需要去实现它。
tryAcquire(int):独占方式。尝试获取资源,成功则返回true,失败则返回falsetryRelease(int):独占方式。尝试释放资源,成功则返回true,失败则返回falsetryAcquireShared(int):共享方式。尝试获取资源。负数表示失败;0表示成功,但没有剩余可用资源;正数表示成功,且有剩余资源。
tryReleaseShared(int):共享方式。尝试释放资源,如果释放后允许唤醒后续等待结点返回true,否则返回false

以ReentrantLock举例
初始为0表示当前是没有线程获得锁的状态,例如当A线程调用lock()时,会调用tryAcquire()来独占该锁并将state+1,此后,其他线程再tryAcquire()时就会失败,直到A线程unlock()到state=0(即释放锁)为止,直到线程调用unlock()释放锁,并且state为0时,其他线程才可以获得该锁,当然锁释放之前A线程是可以继续获得锁的,并且每次重复获得state+1,这就是可重入锁的实现原理,当然A线程释放锁需要释放到state为0为止其他线程才可以获得锁。
再以CountDownLunch举例
任务分为N个子线程去执行,state也初始化为N(注意N要与线程个数一致)。这N个子线程是并行执行的,每个子线程执行完后countDown()一次,state会CAS减1。等到所有子线程都执行完后(即state=0),会unpark()主调用线程,然后主调用线程就会从await()函数返回,继续后余动作。

private volatile int state;

2

acquire(int)
  此方法是独占模式下线程获取共享资源的顶层入口。如果获取到资源,线程直接返回,否则进入等待队列,直到获取到资源为止,且整个过程忽略中断的影响。这也正是lock()的语义,当然不仅仅只限于lock()。获取到资源后,线程就可以去执行其临界区代码了。下面是acquire()的源码:

public final void acquire(int arg) {if (!tryAcquire(arg) &&acquireQueued(addWaiter(Node.EXCLUSIVE), arg))selfInterrupt();
}
  1. tryAcquire()尝试直接去获取资源,如果成功则直接返回(这里体现了非公平锁,每个线程获取锁时会尝试直接抢占加塞一次,而CLH队列中可能还有别的线程在等待);
  2. addWaiter()将该线程加入等待队列的尾部,并标记为独占模式;
  3. acquireQueued()使线程阻塞在等待队列中获取资源,一直获取到资源后才返回。如果在整个等待过程中被中断过,则返回true,否则返回false。
  4. 如果线程在等待过程中被中断过,它是不响应的。只是获取资源后才再进行自我中断selfInterrupt(),将中断补上。

学习的博客并引用过来记录一下http://www.cnblogs.com/waterystone/p/4920797.html

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

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

相关文章

屏幕录像专家6.0_迅捷屏幕录像工具和屏幕录像专家哪个更好用?

随着社会的发展,屏幕录像常常都需要使用,然而有些新手朋友就想知道,到底是电脑中自带的屏幕录像专家好用,还是迅捷屏幕录像工具好用,这两者都是当前使用率比较高的软件,今天小编就为大家分析分析&#xff0…

【转】刨根究底字符编码【2.0版】(2):关键术语解释

上一篇中讲道,字符编码所涉及的面非常广,向下的话,涉及到计算机的底层技术,甚至是硬件实现。 因此,这里就让我们从字符编码涉及到的最基本的术语讲起。大部分术语你可能都已经有了解了,但我们现在从字符编…

Cause: java.sql.SQLSyntaxErrorException: Table ‘Chun.user‘ doesn‘t exist Springboot+MybatisPlus报错

排错:yml配置没问题,可以连接到数据库,导包没问题,数据库里面也有这个库和表, 最终发现是因为表名大小写的问题,因为我直接连接的阿里云服务器上的mysql,而mysql在linux下表名是区分大小写的导…

浏览器字体大小设置_CSS之 浏览器解析样式的过程

阅读本文约需要10分钟大家好,我是你们的导师,经常看我朋友圈的同学应该知道,我每天会在微信上给大家免费提供以下服务!1、长期为你提供最优质的学习资源!2、给你解决技术问题!3、每天在朋友圈里分享优质的技…

angular实现国密算法sm2、sm3和sm4的ts版,基于sm-crypto库实现,前后端实现

ts版,js的话直接根据npm文档调用就可以了! ts提供的方法有问题,所以还换了个思路来实现!而且因为不是nodeJs环境所以const sm4 require(sm-crypto).sm4这个在ts里是报错的导致无法实现,如果是使用的是electron那么使…

【转】.net异步性能测试(包括ASP.NET MVC WebAPI异步方法)

很久没有写博客了,今年做的产品公司这两天刚刚开了发布会,稍微清闲下来,想想我们做的产品还有没有性能优化空间,于是想到了.Net的异步可以优化性能,但到底能够提升多大的比例呢?恰好有一个朋友正在做各种语…

win7关机快捷键_电脑快捷键大全(上)

Windows快捷键1单独按Windows:显示或隐藏“开始”功能表WindowsBREAK:显示“系统属性“对话框WindowsD显示桌面或回复桌面Windows M最小化所有窗口WindowsShiftM:还原最小化的窗口CrtlShiftN:新建文件夹WindowsE:打开“我的电脑”…

Nginx报错:nginx: [emerg] CreateFile() nginx.conf“ failed (3: The system cannot find the path specified

windows下启动nginx报错: nginx: [emerg] CreateFile() “D:\桌面\nginx-1.12.0/conf/nginx.conf” failed (3: The system cannot find the path specified) 路径中带中文了,换个目录就好了

【转】ASP.NET Web API 使用Swagger生成在线帮助测试文档,支持多个GET

以下为教程: 在现有webapi项目中,nuget安装以下两个插件 swagger.net.ui swashbuckle 安装完毕后可以卸载Swagger.NET,此处不需要! 安装完毕后屏蔽以下代码 直接运行调试 在浏览器的目录后面加上/swagger即可跳转到swagger调试页 此时如果没有注释. 项目属性里添加xml注释…

idea提示“ cannot access xxxxxxxx.class“的解决方法,idea的bug

同一个包下的public类使用报错,应该是idea的bug: file -> Invalidate Caches / Restart

电脑屏保在哪里设置_手机屏保调成绿色能护眼?真的吗?

说到护眼,你首先想到的是什么颜色?估计90%的人都会不自觉的想到绿色!因为从小家长和老师都会跟我们说:眼睛累了就多看窗户外的绿色植物。久而久之,一说到护眼,大家脑海里第一个想到的就是绿色。你会看到不少…

【转】c#中@的3种作用

以前只知道在C#中为了写文件路径的\不要加转义符而在前面加上标识符,没想到还有其他的作用 1.忽略转义字符 例如 1 string fileName "D:\\文本文件\\text.txt"; 使用后 1 string fileName "D:\文本文件\text.txt"; 2.让字符串跨行 例如 1…

电脑休眠和睡眠的区别_关机、睡眠、休眠的区别

都知道电脑有关机、睡眠、休眠三种休息模式,但是后两个选项使用的人非常少,大多数人每次用完电脑都会选择立即「关机」。有人是为了让电脑「休息」,有人是为了低碳精神,还有人是因为下班不关电脑要罚款,不管是什么原因…

SpringCloud:学习Docker安装zookeeper,注册服务

1.没镜像就拉取镜像 dockerhub中查看版本 官网 docker pull zookeeper:3.4.14 不加版本号也行,默认拉取最新版 创建并启动容器 docker run -p 2181:2181 --privilegedtrue --name zookeeper01 -d zookeeper –privilegedtrue 容器内用户开启root权限 docker ps…

win10固态硬盘分区 整数_惠普HP笔记本Win10改Win7系统教程

惠普HP笔记本和台式机目前都预装的Win10系统,当然Win7旗舰版才是很多用户喜欢的,不过换装Win7有很多方面比较麻烦,如BIOS设置、U盘启动及方分方面都是很多用户不熟悉的,这里小编就详细分享下惠普笔记本Win10改Win7系统教程(BIOS设…

SpringCloud:学习 Docker安装Consul,注册服务

1.拉取镜像 docker pull consul 2.启动容器 docker run -d -p 8500:8500 --restartalways --nameconsul consul:latest agent -server -bootstrap -ui -node1 -client0.0.0.0 创建容器时没有添加参数 --restartalways ,导致的后果是:当 Docker 重启时…

【转】WebApi 身份认证解决方案:Basic基础认证

参考路径:https://www.cnblogs.com/landeanfen/p/5287064.html 前言:最近,讨论到数据库安全的问题,于是就引出了WebApi服务没有加任何验证的问题。也就是说,任何人只要知道了接口的url,都能够模拟http请求去…

python3.0程序实例_Python3 编程第一步

关于递归和两个变量计算斐波那契&#xff1a; import time #计算递归斐波那契时间消耗 nint(input(请输入一个整数:)) start time.time() def fab(n): if n<1: print(输入有误&#xff01;) return -1 if n1 or n2: return 1 else: return fab(n-1)fab(n-2) print(fab(n)) …

JAVA实现telnet代理,对输入命令拦截

目前只是个简单版本&#xff0c;有一些难点没有突破(vi编辑器的处理) package telnet.server;import jinghai.base.Environment; import telnet.TelnetProxyMain; import telnet.handle.Handle;import java.io.ByteArrayOutputStream; import java.io.IOException; import jav…

【转】C# DataTable使用方法详解

在项目中常常常使用到DataTable,假设DataTable使用得当&#xff0c;不仅能使程序简洁有用&#xff0c;并且可以提高性能&#xff0c;达到事半功倍的效果&#xff0c;现对DataTable的使用技巧进行一下总结。 1、添加引用 1 using System.Data; 2、创建表 1 2 3 4 //创建一个…