什么是管程?

news/2024/11/7 13:32:56/

前言

在并发编程领域,最核心的两个理念就是同步和互斥,并发编程就是围绕这两个核心概念来完成的。

  • 互斥:同一时刻只能有一个线程持有共享资源
  • 同步:多个线程之间协调、互作
    在最初,人们利用信号量机制来实现互斥和同步,但是对于编程人员来说,在编码中嵌入大量的信号量操作,代码冗余,而且出错概率增大,后来就有了面向开发人员更友好的管程。

管程

回顾信号量机制,三个核心:

  • 共享变量S,来表示共享资源的数量
  • PV操作,这是操作系统的两个原语操作。对共享变量的修改只能通过PV操作来进行。
    • P操作,请求资源,S = S -1
    • V 操作,释放资源, S = S + 1

管程就是将对信号量的操作进行了封装,体现了面向对象的思想。

Monitor,管程,也称作监视器。
管程指的是管理共享变量以及对共享变量操作 的过程,来达到线程安全的目的

简单点说,就是将共享变量和对共享变量的操作 进行了封装,访问共享变量必须通过管程提供的方法来实现,管程保证了同一时刻只允许一个线程操作管程

那么对于上面提到的两个核心互斥和同步,管程是如何实现的呢?

  • 互斥,管程的设计理念就是,同一时刻只能有一个线程操作管程(进入管程)
  • 同步:一个线程进入到管程后,其他线程进入等待队列,等待唤醒;同时管程内部可以存在条件变量,对进入管程的线程进行判断,不满足条件会进入该条件变量的等待队列,最终也会进入统一的等待队列。
    原理图:

以就诊的场景为例,一个医生只能接诊一位病人,未被接诊的病人需要在候诊室等待叫号,此时医生是共享变量(共享资源),一个病人就是一个线程,候诊室就是等待队列,拍CT就是条件变量。

  • 一位病人接诊,此时医生发现病人,病人满足所有的条件,就诊完成,病人离开,去候诊室中的叫下一个号的病人。
  • 如果一位病人接诊后,此时医生发现病人不满足条件,还需要去拍CT,病人离开,下一个病人进来,当这个病人做完CT后,重新在候诊室排队等待被叫号。

总结:
管程对共享变量以及对其的操作进行了封装
管程的组成部分:

  • 共享变量
  • 对共享变量的操作
  • 等待队列
    一个管程可以管理多个共享变量。

同一时刻只允许一个线程进入(访问)管程,并修改共享状态变量S = 1, 此时其他线程检测到共享变量被修改,那么就进入到等待队列
进入到管程内的线程,就可以来操作共享的资源了,管程内可以设置条件变量,同时此条件变量也可以拥有一个自己的等待队列,如果线程不满足条件,此线程退出管程,将此线程加入到此条件等待队列中,当在此队列中出队后,然后重新去竞争管程,失败就加入到等待队列中

在C语言中,管程是一个程序结构代码,在面向对象的语言中,管程是一个对象。
JUC中的AQS就是基于管程来实现的,而JUC中的大部分的锁都是继承AQS来实现的。Java中的synchronized中的监视器锁对象也是基于管程实现的。

参考资料

锁原理 - 信号量 vs 管程:JDK 为什么选择管程 - binarylei - 博客园


http://www.ppmy.cn/news/1027894.html

相关文章

注意:阿里云服务器随机分配可用区说明

阿里云服务器如有ICP备案需求请勿选择随机可用区,因为当前地域下的可用区可能不支持备案,阿里云百科分享提醒大家,如果你的购买的云服务器搭建网站应用,网站域名需要使用这台云服务器备案的话,不要随机分配可用区&…

Ubuntu常用压缩指令总结

一、tar tar是Linux系统中最常用的压缩工具之一,它的一个优点是它可以保留文件的权限和所有权信息。tar可以创建.tar文件(通常称为"tarball"),或者与gzip或bzip2等工具结合使用来创建.tar.gz或.tar.bz2文件。gzip工具的…

基于SSM的小型仓库库存管理系统

C00142基于SSM的小型仓库库存管理系统 项目简介项目获取开发环境项目技术运行截图 项目简介 该系统有三类用户分别是管理员、员工、客户。 管理员(登陆后台):可以对以上6个模块进行相应操作,还可以修改自己的密码。 员工&#xf…

二 根据用户行为数据创建ALS模型并召回商品

二 根据用户行为数据创建ALS模型并召回商品 2.0 用户行为数据拆分 方便练习可以对数据做拆分处理 pandas的数据分批读取 chunk 厚厚的一块 相当大的数量或部分 import pandas as pd reader pd.read_csv(behavior_log.csv,chunksize100,iteratorTrue) count 0; for chunk in …

DOM常见的操作有哪些

DOM(文档对象模型)是一种用于表示和操作HTML和XML文档的标准。在JavaScript中,可以使用DOM API来对DOM进行操作 常见的DOM操作: 获取元素: document.getElementById(id): 根据元素的id属性获取元素。document.getElem…

体渲染原理及WebGL实现【Volume Rendering】

体渲染(Volume Rendering)是NeRF神经场辐射AI模型的基础,与传统渲染使用三角形来显示 3D 图形不同,体渲染使用其他方法,例如体积光线投射 (Volume Ray Casting)。本文介绍体渲染的原理并提供Three.js实现代码&#xff…

nlohmann json:类型检查

nlohmann提供了成员函数type(),用于返回当前的json数据类型: constexpr value_t type() const noexcept { return m_type; }using value_t = detail::value_t;enum class value_t : std::uint8_t {null, ///< null valueobject, ///< object…

4. 软件开发的环境搭建

目录 1. 搭建环境 1.1 检查 JDK 1.2 检查 MySQL 数据库 1.3 检查 Maven 1.4 检查 GITEEGIT 1.5 安装插件 1.5.1 安装 Spring Boot Helper 1.5.2 安装 lombok 1.6 创建仓库 1.6.1 登录 GITEE 创建仓库并复制仓库地址 1.6.2 克隆到本地 1.7 创建工程 1.7.1 设置编码…