并发:管程

管程作为并发编程的一种解决方案,提供了互斥和同步功能。文章介绍了管程的概念,强调其相比信号量更易控制。管程的特性包括限制共享变量访问和线程执行顺序。文中讨论了Hoare模型和MESA模型,指出MESA模型通过cnotify避免了额外线程切换,并引入超时计时器防止线程饥饿。Java中的管程基于MESA模型,synchronized关键字支持单一条件变量,而Lock和Condition接口则允许用户自定义多个条件变量的管程实现。
摘要由CSDN通过智能技术生成

1、为什么使用管程?

信号量可以提供线程间的互斥和合作,但是使用信号量来设计一个正确的程序时很困难的,semWait和semSignal可能会分布在整个程序中,很难看出信号量上的这些操作所产生的整体效果。

管程(monitor)是一种程序设计语言结构,它提供与信号量相同的功能,但更容易控制。

2、什么是管程?

管程是包含共享变量以及对共享变量的操作方法的过程,让它们支持并发。

管程的特点:

①共享变量只能被管程中的方法访问,外部过程不能访问;

②一个线程只能通过调用管程的一个方法进行管程;

③任何时候,只能有一个线程在管程中执行,调用管程的其他线程阻塞等待。

前两点特点与面向对象语言中对象的特点很相似。因此,java中使用了管程模型,java中的管程就是管理类的成员变量和成员方法,让这个类线程安全。

3、管程提供的互斥和同步

1)管程中的共享变量每个只能被一个线程访问,因此对共享变量的访问是互斥的。

比如,管程将共享变量queue这个队列和相应的入队enq()、出队deq()操作封装起来,线程A和线程B只能通过调用方法enq()和deq()来访问共享变量queue,而这两个方法不会同时执行,因为只能有一个线程进入管程执行。

2)管程使用条件变量来支持同步。条件变量包含在管程中,并且只能在管程中被访问。两个函数用于操作条件变量:

  • cwait():管程内的执行线程在条件 x 上阻塞,管程现在可以被另一线程使用;
  • csignal():唤醒之前因条件 x 而阻塞的一个线程,如果没有这样的线程,则什么都不做。

当一个线程在管程中执行时,它可能会发现自己不满足某一条件x,通过调用cwait(x)把自己暂时阻塞在条件 x 上,然后它被放入条件 x 的阻塞队列。

当管程中的另一执行线程发现条件变量 x 发送改变,则发送csignal(x),唤醒条件 x 的阻塞队列上的线程。

在这里插入图片描述

4、Hoare模型

在管程发展过程中,先后出现过三种不同的管程模型:Hasen模型、Hoare模型和MESA模型。这里先介绍Hoare模型。

Hoare定义的管程,要求在条件阻塞队列上至少有一个线程,当另一个线程改变了该条件,并发送csignal时,立即运行该条件阻塞队列中的一个线程。因此,产生csignal的线程只能进行如下操作:

  • 如果调用csignal方法是管程中的最后一步,则调用完成后立即退出管程 (Hasen模型强制使用这种方式);
  • 如果调用csignal方法后,还需要继续在管程中执行,此时必须将自身阻塞在管程中。

下面是Hoare管程的一个例子( java实现 )。

示例代码1:

public class BlockQueue<T>{
   
  
  final Lock lock = new ReentrantLock();
  //条件变量:队列不满
  final Condition notFull = lock
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值