管程 java_java里的管程Monitor

什么是管程

管程是一个抽象的概念模型,其封装了一套对共享资源访问的模型,目的是通过一个模型来管理共享资源的访问过程,让可能存在多个进程或线程同时访问一个共享资源时能达到"互斥"和"同步"的效果,管程实现管程模型必须达到下面两点要求

1、管程中的共享变量对于外部都是不可见的,只能通过管程才能访问对应的共享资源。

2、管程是互斥的,某个时刻只能允许一个进程或线程访问共享资源。

3、管程中需要有线程等待队列和相应等待和唤醒操作。

4、必须有一种办法使进程无法继续运行时被阻塞。

我们来理解下上面几个条件:

首先第1点 和第2点我们都能理解,只能通过管程访问共享资源,并且每次只能有一个线程获得管程的执行权,这两个要求理解起来很简单,其实就是为了让线程之间达到互斥的效果。

然后看第3点要求,管程中要有等待队列和响应的等待和唤醒操作,这个也好理解,等待队列和唤醒可以使线程之间达到同步有序的执行。

第4点是比较让人费解的,什么时候线程会无法继续运行呢?为什么要在这个时候提供线程可以进入阻塞的方法。

咱们看一个案例:

场景:假如我们正在开发一个互联网项目;

角色:项目参与人员有产品经理、开发人员、测试人员参与;

限制:只有一个办公室可以使用,一个办公室一次只能容纳一个角色进入。

节点: 每个角色负责对应的节点,产品经理产品文档、开发人员产出项目代码、测试人员测试代码质量、产品进行验收。

条件:开发人员必须有了产品文档之后再产出项目代码、测试人员在开发人员开发完毕了之后进入测试、产品人员在测试完毕了之后进行验收。

在这个场景里面,多个角色就是系统的多个线程,办公室是一个共享资源同一时刻只能有一个角色进入,这个场景里面就有一个阻塞场景,就是当一个开发人员抢到了办公室钥匙之后,进入到办公室,结果发现产品的需求都没有出来,这个时候开发人员是没有办法进行工作的,所以只能一直等,等到有产品文档之后继续下一步,但是这个时候产品是没办法进入办公室工作的,因为锁在开发人员手里,所以开发人员一直等不到需求文档,而产品经理一直进入不了办公室,导致死锁。

那么这里就需要有一种方式,当开发人员发现条件不成立的时候,此时开发人员可以主动的放弃办公室的锁,然后告诉办公室门口的产品经理,让产品经理先进办公室完成工作,开发人员自己则进入一个等待队列,当产品经理完成了工作之后,产品经理通知开发人员,然后自己放弃房间钥匙,等待需求验收再开始下一轮的工作。

最后以这种条件阻塞的方式让获得锁的线程可以主动让出锁,并等待其他线程唤醒再来检测条件,避免了某一个线程因为条件不满足导致任务无法进行,而因为别的线程无法进入到管程里,导致这个条件永远也无法改变锁造成的死锁问题。

下面这张图虽然不严谨,但是有助于你理解整个管程模型:

JAVA中的管程模型 Monitor

通过上面的管程我们再来看JAVA里面的管程Monitor了,JAVA是通过sychronyzed关键字,和wait()、notify、notifyAll() 方法实现了整个管程模型, 与上面标准的管程模型不同的是,JAVA的Monitor属于一种简单的管程模型,因为它并没有使用多个条件变量的队列,不管是竞争锁产生的阻塞,还是拿到锁因为某个条件不合格导致的阻塞,统一都放入一个队列了。

下面我们同样通过一张图来理解Monitor:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值