java并发编程实战《八》管程
管程:并发编程的万能钥匙
为什么 Java 在 1.5 之前仅仅提供了 synchronized 关键字及 wait()、notify()、notifyAll() 这三个看似从天而降的方法?
Java 采用的是管程技术,synchronized 关键字及 wait()、notify()、notifyAll() 这三个方法都是管程的组成部分。而管程和信号量是等价的,所谓等价指的是用管程能够实现信号量,也能用信号量实现管程。但是管程更容易使用,所以 Java 选择了管程。
管程,对应的英文是 Monitor,很多 Java 领域的同学都喜欢将其翻译成“监视器”,这是直译。操作系统领域一般都翻译成“管程”。
管程,指的是管理共享变量以及对共享变量的操作过程,让他们支持并发。翻译为 Java 领域的语言,就是管理类的成员变量和成员方法,让这个类是线程安全的。
在管程的发展史上,先后出现过三种不同的管程模型,分别是:Hasen 模型、Hoare 模型和 MESA 模型。其中,现在广泛应用的是 MESA 模型,并且 Java 管程的实现参考的也是 MESA 模型。
管程解决互斥问题的思路很简单,就是将共享变量及其对共享变量的操作统一封装起来。这是解决了互斥问题,那同步问题呢?
管程里引入了条件变量的概念,而且每个条件变量都对应有一个等待队列,如下图,条件变量 A 和条件变量 B 分别都有自己的等待队列。

2.在java中,每个加锁的对象都绑定着一个管程(监视器)
3.线程访问加锁对象,就是去拥有一个监视器的过程。如一个病人去门诊室看医生,医生是共享资源,门锁锁定医生,病人去看医生,就是访问医生这个共享资源,门诊室其实是监视器(管程)。
4.所有线程访问共享资源,都需要先拥有监视器。就像所有病人看病都需要先拥有进入门诊室的资格。
5.监视器至少有两个等待队列。一个是进入监视器的等待队列一个是条件变量对应的等待队列。后者可以有多个。就像一个病人进入门诊室诊断后,需要去验血,那么它需要去抽血室排队等待。另外一个病人心脏不舒服,需要去拍胸片,去拍摄室等待。
6.监视器要求的条件满足后,位于条件变量下等待的线程需要重新在门诊室门外排队,等待进入监视器。就像抽血的那位,抽完后,拿到了化验单,然后,重新回到门诊室等待,然后进入看病,然后退出,医生通知下一位进入。
总结起来就是,管程就是一个对象监视器。任何线程想要访问该资源,就要排队进入监控范围。进入之后,接受检查,不符合条件,则要继续等待,直到被通知,然后继续进入监视器。
java并发编程实战《八》管程的更多相关文章
- 【Java并发编程实战】-----“J.U.C”:ReentrantReadWriteLock
ReentrantLock实现了标准的互斥操作,也就是说在某一时刻只有有一个线程持有锁.ReentrantLock采用这种独占的保守锁直接,在一定程度上减低了吞吐量.在这种情况下任何的"读/ ...
- Java并发编程实战 02Java如何解决可见性和有序性问题
摘要 在上一篇文章当中,讲到了CPU缓存导致可见性.线程切换导致了原子性.编译优化导致了有序性问题.那么这篇文章就先解决其中的可见性和有序性问题,引出了今天的主角:Java内存模型(面试并发的时候会经 ...
- Java并发编程实战 03互斥锁 解决原子性问题
文章系列 Java并发编程实战 01并发编程的Bug源头 Java并发编程实战 02Java如何解决可见性和有序性问题 摘要 在上一篇文章02Java如何解决可见性和有序性问题当中,我们解决了可见性和 ...
- java并发编程实战《二》java内存模型
Java解决可见性和有序性问题:Java内存模型 什么是 Java 内存模型? Java 内存模型是个很复杂的规范,可以从不同的视角来解读,站在我们这些程序员的视角,本质上可以理解为, Java 内存 ...
- 【Java并发编程实战】----- AQS(四):CLH同步队列
在[Java并发编程实战]-–"J.U.C":CLH队列锁提过,AQS里面的CLH队列是CLH同步锁的一种变形.其主要从两方面进行了改造:节点的结构与节点等待机制.在结构上引入了头 ...
- 【Java并发编程实战】----- AQS(三):阻塞、唤醒:LockSupport
在上篇博客([Java并发编程实战]----- AQS(二):获取锁.释放锁)中提到,当一个线程加入到CLH队列中时,如果不是头节点是需要判断该节点是否需要挂起:在释放锁后,需要唤醒该线程的继任节点 ...
- 【Java并发编程实战】----- AQS(二):获取锁、释放锁
上篇博客稍微介绍了一下AQS,下面我们来关注下AQS的所获取和锁释放. AQS锁获取 AQS包含如下几个方法: acquire(int arg):以独占模式获取对象,忽略中断. acquireInte ...
- 【Java并发编程实战】-----“J.U.C”:CountDownlatch
上篇博文([Java并发编程实战]-----"J.U.C":CyclicBarrier)LZ介绍了CyclicBarrier.CyclicBarrier所描述的是"允许一 ...
- 【Java并发编程实战】-----“J.U.C”:CyclicBarrier
在上篇博客([Java并发编程实战]-----"J.U.C":Semaphore)中,LZ介绍了Semaphore,下面LZ介绍CyclicBarrier.在JDK API中是这么 ...
- 【Java并发编程实战】-----“J.U.C”:Semaphore
信号量Semaphore是一个控制访问多个共享资源的计数器,它本质上是一个"共享锁". Java并发提供了两种加锁模式:共享锁和独占锁.前面LZ介绍的ReentrantLock就是 ...
随机推荐
- 2Git分支问题
1,查看所有分支: git branch *号在哪表明当前分支在哪. 2,新建一个分支: git branch featureq(分支名) 转到该分支下: git checkout featureq ...
- Pandas_数据读取与存储数据(精炼)
# 一,读取 CSV 文件: # 文字解析函数: # pd.read_csv() 从文件中加载带分隔符的数据,默认分隔符为逗号 # pd.read_table() 从文件中加载带分隔符的数据,默认分隔 ...
- mysql yyyy-MM-dd function UNIX_TIMESTAMP('yyyy-MM-dd HH:mm:ss')
mysql yyyy-MM-dd function UNIX_TIMESTAMP('yyyy-MM-dd HH:mm:ss') select UNIX_TIMESTAMP('1997-10-04 22 ...
- 聊聊Spark的分区、并行度 —— 前奏篇
通过之前的文章[Spark RDD详解],大家应该了解到Spark会通过DAG将一个Spark job中用到的所有RDD划分为不同的stage,每个stage内部都会有很多子任务处理数据,而每个sta ...
- linux系统克隆系统盘
本文将介绍两种方式的系统盘的完整的备份,两种方式各有优缺点,需要根据实际情况来进行选择 使用dd的完整镜像克隆的方式 使用tar去备份数据,安装grub的方式 dd方式 优点: 简单,一条命令 dd ...
- 2、Spring Boot配置
1.配置文件 SpringBoot使用一个全局的配置文件,配置文件名是固定的: •application.properties •application.yml 配置文件的作用:修改SpringBoo ...
- 02、Hibernate开发步骤
1.创建Hibernate配置文件(hibernate.cfg.xml) <?xml version="1.0" encoding="UTF-8"?> ...
- ServiceStack.Redis 的 ASP.NET Core 扩展库
给大家安利一款 ServiceStack.Redis 的 ASP.NET Core 扩展库,它是基于 ServiceStack.Redis.Core 开发的. 简单易用,开源免费,使用ASP.NET ...
- webug第十关:文件下载
第十关:文件下载 点击下载 将fname改为download.php....不过好像它的配置有点问题
- 关于steam平台“wallpaper engine”软件出现界面黑屏,但壁纸能播放的问题
前阵子重装电脑后,在使用wallpaper engine这款软件时发现了以下令人疑惑的画面: 点击"设置"和"壁纸选择"界面全是黑的......这还没完,更气人 ...