美文网首页
管程-------线程根源

管程-------线程根源

作者: Leo_up_up | 来源:发表于2020-06-08 23:08 被阅读0次

    管程和信号量是等价的,操作系统原理告诉我们,信号量可以解决所有的并发问题,但是Java语言采用的是管程这样一个概念,不过就像之前说的,他们是等价的,即使用管程可以实现信号量,使用信号量可以实现管程,所以,在JAVA语言世界里面,管程就可以解决所有的并发问题了。

    那么什么是管程呢,管程,就是说,管理共享变量以及对他们的操作,让他们变得安全。

    在并发编程领域,有两个问题,一个是互斥,即保证同一个资源同一时刻只能被一个线程持有,另外一个就是同步,即保证多个线程之间怎么通信,协助。

    管程是怎么处理互斥的呢?

    它将共享变量和对共享变量的操作统一封装了起来,只允许一个线程进入管程,如下图所示:

    管程互斥

    这是管程解决互斥的方法。

    那么多线程怎么解决同步呢?方法很简单。

    管程解决线程同步

    这个是在管程解决线程互斥的基础上进行的,同样是封装了共享变量和对共享变量的操作,上图中的那个最外面的那个框,就是封装的意思,框的上面还有一个入口,入口配备一个入口等待队列,当多个线程想要同时进入时,只能有一个进入,其他的就在等待队列里面等待。

    进入封装的里面后,管程还引入了条件变量的概念,并且每一个条件变量,还配备了一个等待队列。这样的设计,就是为了解决线程的同步问题。

    假设有一个线程T1执行出队操作,不过,有一个前提条件,就是这个队列不能是空的,这个队列不空就是管程里面的条件变量,如果不满足这个条件,那么就会进入到这个条件变量的对应的等待队列里面去。这个时候,是允许第二个线程进入的,此时第二个线程T2进入管程里面执行入队操作,这个操作执行成功后,队列不空这个条件就满足了,此时线程T2要通知线程T1,此时线程T1要从等待队列里面出来,不过不是立刻执行出队操作,而是重新回到入口等待队列里面。

    下面我们再来看看wait(),notify(),notifyall()这三个方法,上面的T1进入等待队列,执行的就是wait()方法,这里我们使用A来代表 队列不空这个条件对象,那么此时调用的就是A.wait()这个方法,当线程T2执行入队成功后,就会调用A.notify()来唤醒T1线程。至于notifyall()这个方法,他会唤醒等待队列里面的所有的线程。

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

    昂是

    相关文章

      网友评论

          本文标题:管程-------线程根源

          本文链接:https://www.haomeiwen.com/subject/ejcnzhtx.html