Java并发框架——同步状态的管理
整个AQS框架核心功能都是围绕着其32位整型属性state进行,一般可以说它表示锁的数量,对同步状态的控制可以实现不同的同步工具,例如闭锁、信号量、栅栏等等。为了保证可见性此变量被声明为volatile,保证每次的原子更新都将及时反映到每条线程上。而对于同步状态的管理可以大体分为两块,一是独占模式的管理,另外是共享模式的管理。通过对这两种模式的灵活变换可以实现多种不同的同步器,如下图,对state的控制可以看成一个管道,管道的大小决定了同时通过的线程,独占模式好比宽度只容许一个线程通过的管道,在这种模式下线程只能逐一通过管道,任意时刻管内只能存在一条线程,这便形成了互斥效果。而共享模式就是管道宽度大于1的管道,可以同时让n条管道通过,吞吐量增加但可能存在共享数据一致性问题。(注意:两种模式的讨论忽略了队列的管理逻辑,实际上CLH
Node的引入是为了优化竞争带来的性能问题,不影响同步状态管理的探讨)
图2-5-9-5 独占模式与共享模式
如何通过state实现独占模式和共享模式?在此之前先了解AQS框架中相关的getState、setState、compareAndSetState三个操作state的基本方法,前两个方法是普通的获取设置方法,其必须保证不存在数据竞争的情况下使用,compareAndSetState方法则提供了CAS方式的硬件级别的原子更新。两种模式就是通过这些方法对state操作实现不同同步模式,下面给出最简单的实现。
独占模式
public boolean tryAcquire(int acquires) {
if (compareAndSetState(0, 1)) {
return true;
}
return false;
}
protected boolean tryRelease(int releases) {
setState(0);
return true;
}
多条线程通过tryAcquire尝试把state变量改为1,由于CAS算法的保证,最终有且仅有一条线程成功修改state,修改成功的线程代表获取锁成功,将拥有往下执行的权利,进入管道。当执行完毕退出管道时执行tryRelease尝试把state变量改为0,让出管道,此处由于不存在线程竞争所以可直接使用setState,接着其他未通过的线程继续重复尝试。
共享模式
public int tryAcquireShared(int interval) {
for (;;) {
int current = getState();
int newCount = current - 1;
if (newCount < 0 || compareAndSetState(current, newCount)) {
return newCount;
}
}
}
public boolean tryReleaseShared(int interval) {
for (;;) {
int current = getState();
int newCount = current + 1;
if (compareAndSetState(current, newCount)) {
return true;
}
}
}
与独占模式不同的是对state的管理及判断条件,独占模式state的值只能为0或1,而共享模式的state是可以被出事换成任意整数,一般初始值表示提供一个同时n条线程通过的管道宽度,这样一来,多条线程通过tryAcquireShared尝试将state的值减去1,成功修改state后就返回新值,只有当新值大于等于0才表示获取锁成功,拥有往下执行的权利,进入管道。在执行完毕时线程将调用tryReleaseShared尝试修改state值使之增加1,表示我已经执行完了并让出管道的通道供后面线程使用,需要说明的是与独占模式不同,由于可能存在多条线程并发释放锁,所以此处必须使用基于CAS算法的修改方法,修改成功后其他线程便可继续竞争锁。
ASQ框架提供了对同步状态state的基本操作,了解了两种模式对state操作开发者可能很自由地自定义自己的同步器。实际中AQS框架在提供state状态管理接口的同时也将维护等待队列的工作,两项工作被封装成一个模板,规定了工作流程,工作流程包括什么条件下加入等待队列、什么条件移除等待节点、如何操作等待队列、需不需要阻塞、支不支持中断等等,对外仅仅提供state状态操作接口供开发者自定义,而队列的维护工作已经绑定在模板中,无需你自己动手。
喜欢研究java的同学可以交个朋友,下面是本人的微信号:
Java并发框架——同步状态的管理的更多相关文章
- Java并发框架——AQS堵塞队列管理(一)——自旋锁
我们知道一个线程在尝试获取锁失败后将被堵塞并增加等待队列中,它是一个如何的队列?又是如何管理此队列?这节聊聊CHL Node FIFO队列. 在谈到CHL Node FIFO队列之前,我们先分析这样 ...
- Java并发框架——AQS阻塞队列管理(一)——自旋锁
我们知道一个线程在尝试获取锁失败后将被阻塞并加入等待队列中,它是一个怎样的队列?又是如何管理此队列?这节聊聊CHL Node FIFO队列. 在谈到CHL Node FIFO队列之前,我们先分析这种队 ...
- Java并发框架——AQS阻塞队列管理(三)——CLH锁改造
在CLH锁核心思想的影响下,Java并发包的基础框架AQS以CLH锁作为基础而设计,其中主要是考虑到CLH锁更容易实现取消与超时功能.比起原来的CLH锁已经做了很大的改造,主要从两方面进行了改造:节点 ...
- Java并发框架——AQS阻塞队列管理(二)——自旋锁优化
看Craig, Landin, and Hagersten发明的CLH锁如何优化同步带来的花销,其核心思想是:通过一定手段将所有线程对某一共享变量轮询竞争转化为一个线程队列且队列中的线程各自轮询自己的 ...
- Java 并发 线程同步
Java 并发 线程同步 @author ixenos 同步 1.异步线程本身包含了执行时需要的数据和方法,不需要外部提供的资源和方法,在执行时也不关心与其并发执行的其他线程的状态和行为 2.然而,大 ...
- Java并发框架AbstractQueuedSynchronizer(AQS)
1.前言 本文介绍一下Java并发框架AQS,这是大神Doug Lea在JDK5的时候设计的一个抽象类,主要用于并发方面,功能强大.在新增的并发包中,很多工具类都能看到这个的影子,比如:CountDo ...
- 深入理解Java并发框架AQS系列(一):线程
深入理解Java并发框架AQS系列(一):线程 深入理解Java并发框架AQS系列(二):AQS框架简介及锁概念 一.概述 1.1.前言 重剑无锋,大巧不工 读j.u.c包下的源码,永远无法绕开的经典 ...
- 深入理解Java并发框架AQS系列(二):AQS框架简介及锁概念
深入理解Java并发框架AQS系列(一):线程 深入理解Java并发框架AQS系列(二):AQS框架简介及锁概念 一.AQS框架简介 AQS诞生于Jdk1.5,在当时低效且功能单一的synchroni ...
- 深入理解Java并发框架AQS系列(四):共享锁(Shared Lock)
深入理解Java并发框架AQS系列(一):线程 深入理解Java并发框架AQS系列(二):AQS框架简介及锁概念 深入理解Java并发框架AQS系列(三):独占锁(Exclusive Lock) 深入 ...
随机推荐
- POJ1509 Glass Beads
Glass Beads Time Limit: 3000MS Memory Limit: 10000K Total Submissions: 4314 Accepted: 2448 Descr ...
- 【SYZOI Round1】滑稽的树
Description zzsyz实验楼里面种了一棵滑稽树,只有滑稽之力达到大乘期的oier才能看到.虽然我们看不到,但是还是知道一些信息: 这真的是一棵树,由n个节点,n-1条边联通.一号滑稽果同时 ...
- OCP 认证考试报名费技巧题库051052053解析合格线
本人于2017年4月22日通过参加OCP考试,第一次参加,一天之内考了三门,三门一次性通过,052 - 95% ,053 - 86% ,051 - 100% 一.关于考试考试报名费: 052:158$ ...
- C# 导入excel报错 :不是预期外部表
错误原因:由于Excel 97-2003的连接格式与Excel 2010 的 不同造成. 解决方案1: 很多人换了2010后,问的最多的问题之一是2003里最经典的ADO中的“provider=Mic ...
- PTA 银行排队问题之单队列多窗口服务
假设银行有K个窗口提供服务,窗口前设一条黄线,所有顾客按到达时间在黄线后排成一条长龙.当有窗口空闲时,下一位顾客即去该窗口处理事务.当有多个窗口可选择时,假设顾客总是选择编号最小的窗口. 本题要求输出 ...
- Linux学习之CentOS(十五)----磁盘管理之 启动挂载(转)
启动挂载 /etc/fstab 及 /etc/mtab 刚刚上面说了许多,那么可不可以在启动的时候就将我要的文件系统都挂好呢?这样我就不需要每次进入 Linux 系统都还要在挂载一次呀!当然可以啰!那 ...
- Tomcat,eclipse热部署的三种方式
热部署是指在你修改项目BUG的时候对JSP或JAVA类进行了修改在不重启WEB服务器前提下能让修改生效.但是对配置文件的修改除外! 怎么说呢?热部署其实用的算少了,热部署怎么说都是个人部署的,大点的公 ...
- web性能优化之--合理使用http缓存和localStorage做资源缓存
一.前言 开始先扯点别的: 估计很多前端er的同学应该遇到过:在旧项目中添加新的功能模块.或者修改一些静态文件时候,当代码部署到线上之后,需求方验收OK,此时你送了一口气,当你准备开始得意于自己的ma ...
- window环境搭建zookeeper,kafka集群
为了演示集群的效果,这里准备一台虚拟机(window 7),在虚拟机中搭建了单IP多节点的zookeeper集群(多IP节点的也是同理的),并且在本机(win 7)和虚拟机中都安装了kafka. 前期 ...
- [self init]
在字典转模型中遇到了这样的代码: #import "HMAppInfo.h" @implementation HMAppInfo - (instancetype)initWithD ...