并发编程已经发展很多年,自分时OS以来就已经存在,相关的理论和技术非常多。 这其中的管程是解决并发编程的关键技术。

什么是管程

指的是管理共享变量以及对共享变量的操作过程,让它们支持并发。 在Java领域即管理类的成员变量和方法,让这个类是线程安全的。
管程的英文是:Monitor, 直译是监视器,在OS领域可意译为管程。

管程(monitor) vs 信号量(semophore)

在OS课程中,我们都会学到信号量,知道可用信号量实现互斥锁和同步变量,分别用来解决并发的两大核心问题:互斥和同步(线程间通信,协作)。而管程和信号量其实是等价的,即:可用信号量实现管程,也能用管程实现信号量。但管程更易使用,所以jdk选择了管程。

MESA模型

在管程的发展史上,先后出现过三种不同的管程模型,分别是:Hasen 模型、Hoare 模型和 MESA 模型。现在广泛应用的是 MESA 模型,Java管程以MESA为参考实现。

管程如何解决互斥问题

管程解决互斥问题的思路就是将共享变量及其对共享变量的操作统一封装起来,同一时刻只允许一个线程进入管程。

管程如何解决线程间同步问题

通过在管程中引入条件变量的概念,且每个条件变量都对应一个等待队列,此处的原理跟信号量实现的条件变量类似。 下面示例是一个阻塞队列的代码实现,其中用到了条件变量。


class BlockingQueue {final Lock lock = new ReentrantLock();// 条件变量:队列不满final Condition notFull = lock.newCondition();// 条件变量:队列不空final Condition notEmpty = lock.newCondition();List<Object> internalQueue = new ArrayList<>();void enq(Object o) throws InterruptedException {lock.lock();try {// 队列已满while (internalQueue.size() >= 5) {notFull.await();}// 入队internalQueue.add(o);// 只要入队了说明当前队列不空,唤醒出列线程notEmpty.signal();} finally {lock.unlock();}}void deq() throws InterruptedException {lock.lock();try {// 当前队列为空,线程在非空条件变量队列等待while (internalQueue.size() == 0) {notEmpty.await();}internalQueue.remove(0);// 只要出列了说明当前队列不满,唤醒入列线程notFull.signal();} finally {lock.unlock();}}
}

注意判断队列满或空的代码段,使用的是while,原因是调用条件变量的signal(),被唤醒的目标线程并非立即执行,且执行时是获取到互斥锁并且从wait后一行开始,所以当它执行时可能条件又不再满足,所以需要再次做判断

总结

Java语言本身对管程的实现做了精简,即只有一个条件变量,且通过synchronized关键字实现不需要显式打开和关闭互斥锁。通过JDK1.5后的并发包可以支持多个条件变量,但需要显式打开和关闭互斥锁。

编程语言中的两大问题互斥和同步都可以通过管程来实现,很多并发工具的底层类也是基于它们实现。

4. Java并发编程-管程相关推荐

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

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

  2. 学习笔记:Java 并发编程②_管程

    若文章内容或图片失效,请留言反馈. 部分素材来自网络,若不小心影响到您的利益,请联系博主删除. 视频链接:https://www.bilibili.com/video/av81461839 配套资料: ...

  3. Java并发编程有多难?这几个核心技术你掌握了吗?

    本文主要内容索引 1.Java线程 2.线程模型 3.Java线程池 4.Future(各种Future) 5.Fork/Join框架 6.volatile 7.CAS(原子操作) 8.AQS(并发同 ...

  4. Java并发编程:JMM和volatile关键字

    Java内存模型 随着计算机的CPU的飞速发展,CPU的运算能力已经远远超出了从主内存(运行内存)中读取的数据的能力,为了解决这个问题,CPU厂商设计出了CPU内置高速缓存区.高速缓存区的加入使得CP ...

  5. 简明高效的 Java 并发编程学习指南

    你好,我是宝令,<Java 并发编程实战>专栏作者,很高兴你能看到这篇内容. 对于一个Java程序员而言,能否熟练掌握并发编程是判断他优秀与否的重要标准之一.因为并发编程是Java语言中最 ...

  6. Java并发编程之介绍

    并发编程简介 将串行执行部分编程并发执行,但要考虑上下文切换和资源调度的时间 并发编程的意义及影响多线程的因素 并发编程的目的是为了让程序运行得更快,但是,并不是启动更多的线程就能让程序最 大限度地并 ...

  7. Java并发编程——volatile

    引 volatile可以看成是轻量级的低配版的Synchronized,他主要是作用于共享变量,保证共享变量的可见性.确保共享变量在主内存中一致地准确的更新通知到各个线程,这是Volatile的可见性 ...

  8. Java并发编程中的若干核心技术,向高手进阶

    来源:http://www.jianshu.com/p/5f499f8212e7 引言 本文试图从一个更高的视角来总结Java语言中的并发编程内容,希望阅读完本文之后,可以收获一些内容,至少应该知道在 ...

  9. Java并发编程实战_一线大厂架构师整理:java并发编程实践教程

    并发编程是Java语言的重要特性之一, 在Java平台上提供了许多基本的并发功能来辅助开发多线程应用程序.然而,这些相对底层的并发功能与上层应用程序的并发语义之间并不存在一种简单而直观的映射关系.因此 ...

最新文章

  1. python画出的雷达图效果-PYTHON绘制雷达图代码实例
  2. python读取中文文件报错-Python3 解决读取中文文件txt编码的问题
  3. linux中kafka主题修改分区,kafka_2.11-2.0.0的部署与配置修改
  4. 鼠标追踪没用_【擺评】赛睿里最好用的小手鼠标---Rival 3
  5. java continue goto_Java中goto和break、continue实现区别
  6. 从 linux内核来看进程与线程的异同
  7. [20170302]什么是fuzzy.txt
  8. python1234出栈_Python数据结构与算法3——栈和队列
  9. RabbitMQ控制台队列标签的含义
  10. 暑期OI大电影——不看后悔整个OI生涯!
  11. 利用反射来实现动态代理
  12. Forms 凭票验证
  13. 煤改气加剧雾霾”“石油焦是祸首”等谣言,你中招了吗?
  14. oracle jde优势介绍,Oracle JDE EnterpriseOne模块的详细功能介绍
  15. IndentationError: expected an indented block报错解决
  16. Java反射创建对象效率高还是通过new创建对象的效率高?
  17. 西电计算机学院王宇平,西安电子科技大学计算机学院硕导介绍:王宇平
  18. C语言:设备管理系统
  19. 雨季车辆天窗漏水解决银弹
  20. 智原深耕网通应用 布建完整ASIC解决方案

热门文章

  1. 培育企业安全基因 永信至诚召开2016年企业安全人才能力提升解决方案发布会...
  2. 关于‘-[UIViewController _loadViewFromNibNamed:bundle:] loaded the “XXXView“ nib but the view outlet wa
  3. Huhu Command 正式发布!实用命令行存取工具
  4. Java实现 蓝桥杯VIP 算法提高 贪吃的大嘴
  5. github问题记录:Failed to connect to github.com port 443: Timed out
  6. php 环回地址,环回地址(127.0.0.1)的作用
  7. Excle Sumif函数和Sumifs函数
  8. HTML静态网页作业——关于我的家乡介绍安庆景点
  9. Android仿简书、淘宝等APP View弹出效果
  10. 切换+banner+base+侧滑