资讯专栏INFORMATION COLUMN

Java并发-管程

lastSeries / 1888人阅读

摘要:那并发里面的理论和模型是什么呢那便要从操作系统中解决并发问题的一种模型管程讲起了。当一个进程使用完管程后,它必须释放管程并唤醒等待管程的某一个进程。总结在并发编程领域,有两大核心问题互斥和同步,而这两个问题,管程模型都可以解决。

为什么需要了解管程

Java并发编程是Java中高级程序员必备的一项技能,但是真正学明白并发编程也并非易事。正如Java并发编程实践中的一句话“编写正确的程序并不容易,而编写正确的并发程序就更难了”,Java里并发的知识很琐碎,看懂难,会用更难。然后,我们常常一头扎进了Java并发编程技术的细节,却发现剪不断理还乱,终不得要领。这是因为我们忽略了技术背后的理论和模型,而理论和模型往往比具体的技术更为重要。那Java并发里面的理论和模型是什么呢?那便要从操作系统中解决并发问题的一种模型管程讲起了。

什么是管程

管程是将共享变量及对共享变量的操作封装起来的管理程序。操作系统中的描述为:代表共享资源的数据结构,以及由对该共享数据结构实施操作的一组过程所组成的资源管理程序,共同构成了一个操作系统的资源管理模块,我们称之为管程。管程的示意图如下:

管程如何解决互斥

管程内部的数据结构,仅能被管程内部的过程所访问,任何管程外的过程都不能访问它;反之,局部于管程内部的过程也仅能访问管程内的数据结构。由此可见,管程相当于围墙,它把共享变量和对它进行操作的若干过程围了起来,所有进程要访问临界资源时,都必须经过管程(相当于通过围墙的门)才能进入,而管程每次只准许一个进程进入管程,从而实现了进程互斥。即当一个进程使用管程时,另一个进程必须等待。当一个进程使用完管程后,它必须释放管程并唤醒等待管程的某一个进程

管程如何解决同步

管程里引入了条件变量的概念来解决同步问题,而且每个条件变量都对应有一个等待队列,条件变量对应的3个方法为wait()、notify()、notifyAll()。示意图如下:

线程先在入口等待队列排队进入管程,这确保了互斥访问管程。当线程进入管程后,如果发现条件变量A不满足,则需要调用A.wait()使线程进入A的条件变量等待队列,此时其他在入口等待队列的线程可以继续进入管程。如果当条件变量A满足条件时,则调用A.notify()或则A.notifyAll()(notify是通知等待队列中的一个线程,notifyAll是通知所有线程)方法通知在A条件变量等待队列中的线程,然后该线程会重新进入入口等待队列中排队进入管程。如此便实现了线程间的同步。
这与就医流程相似,患者挂了号后,然后就到就诊门口分诊,等待叫号(类似入口等待队列);当叫到自己的号时,患者就可以找大夫就诊了,就诊过程中,大夫开了个验血的单子(类似条件等待队列)那现在就需求去验血的队伍里排队,同时医生可以给其他患者诊治;等患者做完检查,拿到检查报告后需要重新排队分诊(线程重新进入入口等待队列)。

总结

在并发编程领域,有两大核心问题:互斥和同步,而这两个问题,管程模型都可以解决。管程模型中利用入口等待队列,保证同一时间只有一个线程进入管程,实现线程间的互斥;利用条件变量及条件变量等待队列实现线程间的同步。Java中的synchronized以及lock都是管程模型的一种实现,了解了管程模型后,对后续深入学习Java并发大有好处。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/76063.html

相关文章

  • [Java并发-6]“管程”-java管程初探

    摘要:语言在之前,提供的唯一的并发原语就是管程,而且之后提供的并发包,也是以管程技术为基础的。但是管程更容易使用,所以选择了管程。线程进入条件变量的等待队列后,是允许其他线程进入管程的。并发编程里两大核心问题互斥和同步,都可以由管程来帮你解决。 并发编程这个技术领域已经发展了半个世纪了。有没有一种核心技术可以很方便地解决我们的并发问题呢?这个问题, 我会选择 Monitor(管程)技术。Ja...

    Steve_Wang_ 评论0 收藏0
  • Java 并发学习笔记(二)

    摘要:请参看前一篇文章并发学习笔记一原子性可见性有序性问题六等待通知机制什么是等待通知机制当线程不满足某个条件,则进入等待状态如果线程满足要求的某个条件后,则通知等待的线程重新执行。经极客时间并发编程实战专栏内容学习整理 请参看前一篇文章:Java 并发学习笔记(一)——原子性、可见性、有序性问题 六、等待—通知机制 什么是等待通知—机制?当线程不满足某个条件,则进入等待状态;如果线程满足要...

    zgbgx 评论0 收藏0
  • Java Monitor(管程

    摘要:当前线程使用将对象头的替换为锁记录指针,如果成功,当前线程获得锁如果失败,表示其他线程竞争锁,当前线程便尝试使用自旋来获取锁。重量级锁是悲观锁的一种,自旋锁轻量级锁与偏向锁属于乐观锁。 操作系统在面对线程间同步的时候,会支持例如semaphore信号量和mutex互斥量等同步原语,而monitor是在编程语言中被实现的,下面介绍一下java中monitor(监视器/管程:管理共享变量以...

    caspar 评论0 收藏0
  • [Java并发-2]Java如何解决可见性问题的

    摘要:诞生之处就支持多线程,所以自然有解决这些问题的办法,而且在编程语言领域处于领先地位。,线程规则这条是关于线程启动的。在语言里面,的语义本质上是一种可见性,意味着事件对事件来说是可见的,无论事件和事件是否发生在同一个线程里。 之前我们说了:1,可见性2,原子性3,有序性3个并发BUG的之源,这三个也是编程领域的共性问题。Java诞生之处就支持多线程,所以自然有解决这些问题的办法,而且在编...

    lk20150415 评论0 收藏0
  • [Java并发-5]用“等待-通知”机制优化循环等待

    摘要:在这个等待通知机制中,我们需要考虑以下四个要素。何时等待线程要求的条件不满足就等待。是会随机地通知等待队列中的一个线程,而会通知等待队列中的所有线程。 由上一篇文章你应该已经知道,在 破坏占用且等待条件 的时候,如果转出账本和转入账本不满足同时在文件架上这个条件,就用死循环的方式来循环等待,核心代码如下: // 一次性申请转出账户和转入账户,直到成功 while(!actr.apply...

    fxp 评论0 收藏0

发表评论

0条评论

lastSeries

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<