JavaStorm 关注公众号获取更多并发

在吃透 Syncchronized 原理 中介绍了关于 Synchronize的实现原理,无论是同步方法还是同步代码块,无论是ACC_SYNCHRONIZED还是monitorentermonitorexit都是基于Monitor实现的,那么这篇来介绍下什么是Monitor

所谓管程:指的是管理共享变量以及对共享变量的操作过程,让它们支持并发。翻译为 Java 就是管理类的成员变量和成员方法,让这个类是线程安全的。

是一种程序结构,结构内的多个子程序(对象或模块)形成的多个工作线程互斥访问共享资源。这些共享资源一般是硬件设备或一群变量。管程实现了在一个时间点,最多只有一个线程在执行管程的某个子程序。与那些通过修改数据结构实现互斥访问的并发程序设计相比,管程实现很大程度上简化了程序设计。 管程提供了一种机制,线程可以临时放弃互斥访问,等待某些条件得到满足后,重新获得执行权恢复它的互斥访问。

MESA 模型

在管程的发展史上,先后出现过三种不同的管程模型,分别是:Hasen 模型、Hoare 模型和 MESA模型。其中,现在广泛应用的是 MESA 模型,并且 Java 管程的实现参考的也是 MESA 模型。所以今天我们重点介绍一下MESA 模型。

在并发领域,有两个核心问题:一个是互斥,一个是同步。管程就是来解决这两个问题的。

  • 互斥:同一时刻只允许一个线程访问共享资源。
  • 同步:线程之间如何通信、协作。

管程互斥与同步实现

它的思路很简单,将共享变量以及对共享变量的操作统一封装起来。如下图所示,管程 A 将共享变量 data 和相关的操作入队enq()、出队deq() 封装起来。线程 A 和线程 B想访问共享变量 data ,只能通过调用管程提供的 enq()deq() 。当然前提是 enq()deq() 保证互斥性,只允许一个线程进入管程。是不是很有面向对象的感觉。

()

在管程模型里,共享变量和对共享变量的操作是被封装起来的,图中最外层的框就代表封装的意思。框的上面只有一个入口,并且在入口旁边还有一个入口等待队列。当多个线程同时试图进入管程内部时,只允许一个线程进入,其他线程则在入口等待队列中等待。这个过程类似就医流程的分诊,只允许一个患者就诊,其他患者都在门口等待。

管程里还引入了条件变量的概念,而且每个条件变量都对应有一个等待队列,如下图,条件变量 A 和条件变量 B 分别都有自己的等待队列。

通过条件通知去唤醒等待队列的线程竞争 锁资源。

我们通过一段代码说明,实现一个阻塞队列,队列分别有出队与入队,都是要先获取互斥锁,就像管程中的入口。

  1. 对于入队操作,如果队列已满,就需要等待直到队列不满,所以这里用了notFull.await();
  2. 对于出队操作,如果队列为空,就需要等待直到队列不空,所以就用了notEmpty.await();
  3. 如果入队成功,那么队列就不空了,就需要通知条件变量:队列不空notEmpty对应的等待队列。
  4. 如果出队成功,那就队列就不满了,就需要通知条件变量:队列不满notFull对应的等待队列。
public class BlockedQueue<T>{final Lock lock = new ReentrantLock();// 条件变量:队列不满  final Condition notFull = lock.newCondition();// 条件变量:队列不空  final Condition notEmpty = lock.newCondition();// 入队void enq(T x) {lock.lock();try {while (队列已满){// 等待队列不满 notFull.await();}  // 省略入队操作...// 入队后, 通知可出队notEmpty.signal();}finally {lock.unlock();}}// 出队void deq(){lock.lock();try {while (队列已空){// 等待队列不空notEmpty.await();}// 省略出队操作...// 出队后,通知可入队notFull.signal();}finally {lock.unlock();}  }
}

在这段示例代码中,我们用了 Java 并发包里面的 Lock 和 Condition,如果你看着吃力,也没关系,后面我们还会详细介绍,这个例子只是先让你明白条件变量及其等待队列是怎么回事。需要注意的是:await() 和前面我们提到的 wait() 语义是一样的;signal() 和前面我们提到的 notify() 语义是一样的。管程通过条件队列通信实现了同步,为我们 Java中的并发编程提供了基本支持。

关注公众号 JavaStorm 获取更多并发原理

管程(Moniter): 并发编程的基本心法相关推荐

  1. asyncio 文件io高并发_python教程:使用 async 和 await 协程进行并发编程

    python 一直在进行并发编程的优化, 比较熟知的是使用 thread 模块多线程和 multiprocessing 多进程,后来慢慢引入基于 yield 关键字的协程. 而近几个版本,python ...

  2. python并发之协程_python并发编程之协程

    一 引子 本节的主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此我们需要先回顾下并发的本质:切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去 ...

  3. 『Python学习笔记』Python实现并发编程(补充joblibpymysql)

    Python实现并发编程(补充joblib&pymysql) 文章目录 一. 并发编程知识点 1.1. 为什么引入并发编程 1.2. 如何选择多线程多进程多协程 1.2.1. 什么是CPU密集 ...

  4. 【极客时间】《Java并发编程实战》学习笔记

    目录: 开篇词 | 你为什么需要学习并发编程? 内容来源:开篇词 | 你为什么需要学习并发编程?-极客时间 例如,Java 里 synchronized.wait()/notify() 相关的知识很琐 ...

  5. 《Java 并发编程实战》--读书笔记

    Java 并发编程实战 注: 极客时间<Java 并发编程实战>–读书笔记 GitHub:https://github.com/ByrsH/Reading-notes/blob/maste ...

  6. python线程池模块_python并发编程之进程池,线程池,协程

    需要注意一下 不能无限的开进程,不能无限的开线程 最常用的就是开进程池,开线程池.其中回调函数非常重要 回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去 ...

  7. Java并发编程原理与实战六:主线程等待子线程解决方案

    Java并发编程原理与实战六:主线程等待子线程解决方案 参考文章: (1)Java并发编程原理与实战六:主线程等待子线程解决方案 (2)https://www.cnblogs.com/pony1223 ...

  8. 并发编程协程(Coroutine)之Gevent

    并发编程协程之Gevent Gevent官网文档地址:http://www.gevent.org/contents.html 基本概念 我们通常所说的协程Coroutine其实是corporate r ...

  9. python并发编程之协程

    python并发编程之协程 1.协程: 单线程实现并发 在应用程序里控制多个任务的切换+保存状态 优点: 应用程序级别速度要远远高于操作系统的切换 缺点: 多个任务一旦有一个阻塞没有切,整个线程都阻塞 ...

  10. python线程池模块_python并发编程之进程池,线程池,协程(Python标准模块--concurrent.futures(并发未来))...

    需要注意一下 不能无限的开进程,不能无限的开线程 最常用的就是开进程池,开线程池.其中回调函数非常重要 回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去 ...

最新文章

  1. 轻轻一扫,立刻扣款,付款码背后的原理你不想知道吗?
  2. python教程下载地址-最新python实战教程网盘下载地址
  3. 安卓CheckBox实现单选
  4. 蚂蚁御术:我的前端十年成长之路
  5. 06- 本地方法接口
  6. cf13C Sequence(DP)
  7. Mac下搭建Cocos2d-x-3.2的开发环境详解
  8. JAVA开发的人力资源管理系统
  9. 免费试用版CRM客户管理系统如何选择?
  10. ECharts绘制中国地图、广西地图
  11. 用批量重命名技巧把文件夹下多个文件快速重命名
  12. 基于ZYNQ、AM5728、AM5708、AM437x、AM335x、STM32+FPGA等平台提供了开源EtherCAT主站IgH案例
  13. 群晖Docker青龙面板部署方法V2.11.0
  14. 操作系统MSXML组件版本过低,导致启动失败的原因
  15. 使用高德地图根据坐标点画出路线
  16. How to Add a Dotted Underline Beneath HTML Text
  17. 程序在计算机中是如何运行起来的
  18. 恒生电子2023年实习春招笔试第二题(编程)
  19. 【蓝桥杯】历届试题 青蛙跳杯子(广度优先搜索bfs)
  20. AM-Softmax

热门文章

  1. Java获取当前电脑的ip地址
  2. 创建student-dissertation数据库
  3. html 汉字美化,HTML5 | 0 0 6 - 美化字体
  4. c语言eval函数,百行代码轻便实现C#中的Eval函数
  5. 技术总监7年总结,如何进行正确的沟通?
  6. 2022起重机械指挥考试题模拟考试题库及在线模拟考试
  7. 桌面应用程序与web应用程序
  8. api文档 luci_开发OpenWrt路由器上LuCI的模块
  9. App 抓包提示网络异常怎么破?
  10. nginx: [warn] the “user“ directive makes sense only if the master process runs with super-user privi