文档详情

java并发编程实战管程.pdf

发布:2025-05-01约8.41千字共9页下载文档
文本预览下载声明

08|管程:并发编程的

2019-03-16

00:0012:01



讲述:讲述:讲述:大小:11.02M大小:11.02M大小:11.02M

并发编程这个技术领域已经发展了半个世纪了,相关的理论和技术纷繁复杂。那有没有一种

技术可以很方便地解决我们的并发问题呢?这个问题如果让我选择,我一定会选择管程技术。

Java语言在1.5之前,提供的唯一的并发原语就是管程,而且1.5提供的SDK并发包,也

是以管程技术为基础的。除此之外,C/C++、C#等高级语言也都支持管程。

可以这么说,管程就是一把解决并发问题的。

什么是管程

不知道你是否曾思考过这个问题:为什么Java在1.5之前仅仅提供了synchronized关键字及

wait()、notify()、notifyAll()这三个看似从天而降的方法?在刚接触Java的时候,我以为它会

提供信号量这种编程原语,因为操作系统原理课程告诉我,用信号量能解决所有并发问题,结果

我发现不是。后来我找到了:Java采用的是管程技术,synchronized关键字及wait()、

notify()、notifyAll()这三个方法都是管程的组成部分。而管程和信号量是等价的,所谓等价指的

是用管程能够实现信号量,也能用信号量实现管程。但是管程更容易使用,所以Java选择了管

管程,对应的英文是Monitor,很多Java领域的同学都喜欢将其翻译成“监视器”,这是直

译。操作系统领域一般都翻译成“管程”,这个是意译,而也更倾向于使用“管程”。

所谓管程,指的是管理共享变量以及对共享变量的操作过程,让他们支持并发。翻译为Java领

域的语言,就是管理类的成员变量和成员方法,让这个类是线程安全的。那管程是怎么管的呢?

MESA模型

在管程的发展史上,先后出现过三种不同的管程模型,分别是:Hasen模型、Hoare模型和

MESA模型。其中,现在广泛应用的是MESA模型,并且Java管程的实现参考的也是MESA

模型。所以今天我们重点介绍一下MESA模型。

在并发编程领域,有两大问题:一个是互斥,即同一时刻只允许一个线程共享资源;另

一个是同步,即线程之间如何通信、协作。这两大问题,管程都是能够解决的。

我们先来看看管程是如何解决互斥问题的。

管程解决互斥问题的思路很简单,就是将共享变量及其对共享变量的操作统一封装起来。在下图

中,管程X将共享变量queue这个队列和相关的操作入队enq()、出队deq()都封装起来了;

线程A和线程B如果想共享变量queue,只能通过调用管程提供的enq()、deq()方法来实

现;enq()、deq()保证互斥性,只允许一个线程进入管程。不知你有没有发现,管程模型和面向

对象高度契合的。估计这也是Java选择管程的吧。而我面章节介绍的互斥锁用法,其

背后的模型其实就是它。

管程模型的代码化语义

那管程如何解决线程间的同步问题呢?

这个就比较复杂了,不过你可以借鉴一下我们曾经提到过的就医流程,它可以帮助你快速地理解

这个问题。为进一步便于你理解,在下面,我展示了一幅MESA管程模型示意图,它详细描述了

MESA模型的主要组成部分。

在管程模型里,共享变量和对共享变量的操作是被封装起来的,图中最外层的框就代表封装的意

思。框的上面只有一个,并且在旁边还有一个等待队列。当多个线程同时试

显示全部
相似文档