临界区、管程、信号量介绍

2024-06-04 03:48
文章标签 介绍 信号量 管程 临界

本文主要是介绍临界区、管程、信号量介绍,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

临界区、管程、信号量是操作系统对并发编程支持的三个概念。它们并不是属于java,而是属于操作系统(目前我知道 linux有这三个概念,我觉得windows也应该有只是不确定,否则怎么会支持多核CPU呢?)。

临界区

临界区是线程需要互斥执行的一段代码。临界区的资源是线程共享的,但是执行的返回结果是不确定的。 举个例子:linux系统中的fork()命令会开启一个子线程,每个子线程都应该去调用父线程的方法返回一个PID。假设这个方法是:

NEW_PID = next_pid++

上面的next_pid就是临界资源,是多个线程共享的, 这段代码不是原子操作,但是一定要是互斥的。 临界区只是一个概念,具体实现要看编程语言还操作系统。

信号量

信号量也是一个编程概念,基本由一个整数变量,和两个原子操作组成。这两个原子操作对这个整数变量对行增加和删除。成功才执行后面的代码,失败则阻塞。 具体代码实现可以看我的另一篇博客。
https://blog.csdn.net/u011296165/article/details/80249229

管程

管程对应的英文是Monitor。管程的定义是管理共享变量以及对共享变量的操作过程,让它们支持并发。相对应的java语意是管理java类的成员变量和成员方法,让这个类是线程安全的。
管程是编程语言提供的一种抽象数据结构,它有两个特点

  1. 互斥访问,即任一时刻只有一个线程在执行管程代码;
  2. 正在管程内的线程可以放弃对管程的控制权;
    条件变量(condition variable)是管程内部的实现机制,每个条件变量都代表一种等待的原因,也对应一个等待队列。条件变量有两个操作:wait和signal。这两个条件变量的操作,是某种情况下等待和在某种情况下执行。

MESA模型----java管程使用的模型

管程实现互斥

管程实现互斥就是将共享变量和对共享变量操作的方法封闭起来。如下图,管程X将共享变量queue这个队列和相关操作入队enq()和deq()都封装起来。线程A和线程B如果想要访问共享变量queue()队列,就要使用enq()和deq()方法,enq()和deq()保持了互斥性,这样来保证线程安全。

管程实现同步

MESA的模型图
在这里插入图片描述

图中最大的方框就代表封装的意思, 上方开口就是管程的入口, 入口旁边有一个等待队列。一个管程只能有一个线程去执行,其他线程就进入到这个等待队列。 就像是去医院看医生,一个医生只能同时给一个病人看病,其他拿到号的病人都会在门外等着。

管程里面还有一个条件变量的概念,管程里面还有一个条件变量的概念,管程里面还有一个条件变量的概念这一定非常重要。 后面的东西都是使用了这个条件变量。每一个条件变量都有自己的等待队列,就如图上的条件变量A和条件变量B有两个等待队列。

现在对他的执行过程做一个说明。我们管程中通常两个方法,方法X代表出队操作,方法Y代表入队操作。我们的共享变量V就是队列。我们的假设线程T1在执行方法X出队操作,那么在执行这个出队操作之前是不是应用有一个前置条件,判断这个共享变量V队列不能为空。 而这个前置条件就是条件变量。条件变量的等待队列就是无法获取条件的时候,条件变量执行了wait()方法,将线程放入到了这个条件变量的等待队列中了。
举个生活中的例子:小明去医院看医生,第一步、进医院的就是去取号,然后去对应医生办公室门口等待叫号。这一步对应的就管程入口等待对列第二步 叫到号之后医生让小明去拍X光片,他就去抽血处排队抽血。这一步对应的就是条件变量等待对列第三步 抽完血之后,小明又要去医生办公室门口等待叫号,这一步对应的就是当条件变量符合执行条件就从条件变量队列中释放,但并不是马上去执行,而是去管程入口队列中等待。第四步,小明进入医生办公室看医生,医生让小明在去验上血。小明就要去验血处等待。这一步对应的就是当线程第二次进入管程中,发现条件变量又不符合了,又要去重新进入条件变量队列中重新等待条件符合要求。 当符合要求后在次进入管程入口等待队列,直到进入管程后条件符合要求去执行方法完成。
这里可能有点绕,还请多看几遍。
下面用代码做一下示范。
假定对象A代表“队列不空”这个条件,那么线程进入管程需要判断队列是否为空,如果为空则调用 A.wait()方法。同理当“条件 不空”这个条件满足时,线程T2需要调用 A.notify()来通知A等待队列中的一个线程。 也可以调用 notifyAll()这个方法。

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();}  }
}
  1. 对于入队操作,如果队列已满。就需要等待直接队列不满,所以这就用notFull.await()。
  2. 对于出队操作,如果队列为空,就需要等待直接到队不空,所以这就用notEmpty.await()。
  3. 如果入队成功,那么队列就不空,就需要通知队列不空的等待队列。这里就要用notEmpty.signal();
  4. 如果出队成功,那就队列就不满,就需要通知队列不满的等待队列。就这里要用notFull.signal();

总结

java MESA模型
在这里插入图片描述
java MESA 模型中只有一个条件变量,是使用synchronized关键字来实现的。而java sdk并发包中支持多个条件变量,需要开发人员手动去调用加锁和解锁操作。

注:
借鉴极客时间java并发编程和另外一篇博客,那篇博客因电脑突然关机找不到了,如发现请通知,我在加上链接。

这篇关于临界区、管程、信号量介绍的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1028976

相关文章

MySQL常用字符串函数示例和场景介绍

《MySQL常用字符串函数示例和场景介绍》MySQL提供了丰富的字符串函数帮助我们高效地对字符串进行处理、转换和分析,本文我将全面且深入地介绍MySQL常用的字符串函数,并结合具体示例和场景,帮你熟练... 目录一、字符串函数概述1.1 字符串函数的作用1.2 字符串函数分类二、字符串长度与统计函数2.1

zookeeper端口说明及介绍

《zookeeper端口说明及介绍》:本文主要介绍zookeeper端口说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、zookeeper有三个端口(可以修改)aVNMqvZ二、3个端口的作用三、部署时注意总China编程结一、zookeeper有三个端口(可以

Python中win32包的安装及常见用途介绍

《Python中win32包的安装及常见用途介绍》在Windows环境下,PythonWin32模块通常随Python安装包一起安装,:本文主要介绍Python中win32包的安装及常见用途的相关... 目录前言主要组件安装方法常见用途1. 操作Windows注册表2. 操作Windows服务3. 窗口操作

c++中的set容器介绍及操作大全

《c++中的set容器介绍及操作大全》:本文主要介绍c++中的set容器介绍及操作大全,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录​​一、核心特性​​️ ​​二、基本操作​​​​1. 初始化与赋值​​​​2. 增删查操作​​​​3. 遍历方

HTML img标签和超链接标签详细介绍

《HTMLimg标签和超链接标签详细介绍》:本文主要介绍了HTML中img标签的使用,包括src属性(指定图片路径)、相对/绝对路径区别、alt替代文本、title提示、宽高控制及边框设置等,详细内容请阅读本文,希望能对你有所帮助... 目录img 标签src 属性alt 属性title 属性width/h

MybatisPlus service接口功能介绍

《MybatisPlusservice接口功能介绍》:本文主要介绍MybatisPlusservice接口功能介绍,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友... 目录Service接口基本用法进阶用法总结:Lambda方法Service接口基本用法MyBATisP

MySQL复杂SQL之多表联查/子查询详细介绍(最新整理)

《MySQL复杂SQL之多表联查/子查询详细介绍(最新整理)》掌握多表联查(INNERJOIN,LEFTJOIN,RIGHTJOIN,FULLJOIN)和子查询(标量、列、行、表子查询、相关/非相关、... 目录第一部分:多表联查 (JOIN Operations)1. 连接的类型 (JOIN Types)

java中BigDecimal里面的subtract函数介绍及实现方法

《java中BigDecimal里面的subtract函数介绍及实现方法》在Java中实现减法操作需要根据数据类型选择不同方法,主要分为数值型减法和字符串减法两种场景,本文给大家介绍java中BigD... 目录Java中BigDecimal里面的subtract函数的意思?一、数值型减法(高精度计算)1.

Pytorch介绍与安装过程

《Pytorch介绍与安装过程》PyTorch因其直观的设计、卓越的灵活性以及强大的动态计算图功能,迅速在学术界和工业界获得了广泛认可,成为当前深度学习研究和开发的主流工具之一,本文给大家介绍Pyto... 目录1、Pytorch介绍1.1、核心理念1.2、核心组件与功能1.3、适用场景与优势总结1.4、优

Java实现本地缓存的常用方案介绍

《Java实现本地缓存的常用方案介绍》本地缓存的代表技术主要有HashMap,GuavaCache,Caffeine和Encahche,这篇文章主要来和大家聊聊java利用这些技术分别实现本地缓存的方... 目录本地缓存实现方式HashMapConcurrentHashMapGuava CacheCaffe