java管程 实现,Java中的管程模型

423f83d389bd

Java中的管程模型

操作系统使用信号量解决并发问题,Java选择使用管程(Monitor)解决并发问题。信号量和管程是等价的,可以使用信号量实现管程,也可以使用管程实现信号量。

管程就是指管理共享变量,以及对共享变量的相关操作。具体到 Java 语言中,管程就是管理类的成员变量和方法,让这个类是线程安全的。管程的发展史中,先后出现过三种管程模型,Hasen 模型、Hoare 模型和 MESA 模型,Java 使用的是 MESA 模型。

我们用管程模型主要是解决并发编程中的两个核心问题,互斥和同步。互斥是指同一时刻只允许一个线程访问共享资源,同步则是指线程之间如何通信、写作。

那么,Java 所采用的 MESA 模型是如何解决互斥和同步问题的呢?

MESA 解决互斥问题

管程模型解决互斥问题的方法是:将共享变量及对共享变量的操作统一封装起来。

如下图所示,管程 X 将共享变量 queue,及其入队出队操作 enq() 和 dep() 封装起来。线程 A 和线程 B 想要访问共享变量 queue,就需要通过 enq() 和 deq() 来实现,而 enq() 和 deq() 保证互斥,只允许一个线程进入管程。

423f83d389bd

管程模型的代码化语义

MESA 解决同步问题

MESA 模型解决同步问题可以类比去医院就医。患者首先需要排队等待医生叫好,医生诊断被叫到号的患者。期间,患者如果需要进行其他辅助的检查,比如说排个 X 光,就需要去等待拍 X 光的医生叫好。患者拍完 X 光之后,再次回到上一个医生那里,等待医生再次诊断。

423f83d389bd

医院排队

管程模型与看医生的流程类似,管程入口处有一个等待队列。当多个线程试图进入管程内部的时候,只允许一个线程进入,其他线程在等待队列中等待。就和看医生的时候排队一样。

管程中还有一个条件变量的概念,每个条件变量对应一个条件变量等待队列。比如说有一个条件变量 A,当执行线程 T1 时发现不满足条件变量 A,T1 就会进入条件变量 A 的等待队列中。就像去看医生,医生让你先去排个 X 光,就要去拍 X 光的地方排队。

当执行线程 T2 时发现满足条件变量 A,就会唤醒条件变量 A 等待中的线程 T1,线程 T1 就会再次进入到入口等待队列。就像拍完 X 光的人,再去看医生。

423f83d389bd

MESA 管程模型

public class BlockedQueue{

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();

}

}

}

对于入队操作,如果队列已满,就需要等待直到队列不满,所以这里用了notFull.await();。

对于出队操作,如果队列为空,就需要等待直到队列不空,所以就用了notEmpty.await();。

如果入队成功,那么队列就不空了,就需要通知条件变量:队列不空notEmpty对应的等待队列。

如果出队成功,那就队列就不满了,就需要通知条件变量:队列不满notFull对应的等待队列。

synchronized 单条件变量的管程模型

Java 参考了 MESA 模型,语言内置的管程(synchronized)对 MESA 模型进行了精简。MESA 模型中,条件变量可以有多个,Java 语言内置的管程里只有一个条件变量。

Java SDK 并发包实现的管程支持多个条件变量,不过并发包里的锁,需要开发人员自己进行加锁和解锁操作。

423f83d389bd

Java 中的管程示意图

相关文章

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值