JYe*_*ton 16
"更好"取决于背景.根据詹姆斯麦克帕兰的说法,他们"同样强大".我强烈建议您查看他的博客,讨论差异.
这是我发现的快速指南:
信号灯
Wait() 并不总是阻止调用者(即,当信号量计数器大于零时).Signal() 要么释放被阻止的线程,如果有,要么增加信号量计数器.Signal()释放阻塞的线程,则调用者和释放的线程都会继续.条件变量
Wait() 总是阻止来电者.Signal() 或者释放一个被阻塞的线程,如果有一个,或者信号丢失就像它永远不会发生一样.Signal()释放被阻塞的线程,则调用者将生成监视器(Hoare类型)或继续(Mesa类型).只有一个调用者或已释放的线程可以继续,但不能同时继续.此信息来自:http://www.cs.mtu.edu/~shene/NSF-3/e-Book/MONITOR/sema-vs-monitor.html
一些有用的资源:
如果您在头痛最小化之后,更喜欢监视器(synchronized块/方法)而不是您认为真正选择锁定原语的信号量.忽略大学关于信号量灵活性的讨论.你是在追求可靠性,而不是可配置性,不是吗?
通常声称监视器和信号量是等效的(可以相互模拟),但这种等效性比有时预期的更抽象,更有帮助.任何能够正确模拟另一个人的人都不再需要这个问题的任何答案了.
显然,在允许同时进入块的线程数大于1的情况下,信号量是唯一可行的选择.因此,监视器的真正竞争对手是二进制信号量,即那些初始化为1的那些信号量,另外只有那些你希望锁定相同的线程最终解锁信号量的信号量.让我们仔细看看那些情况.
监视器和二进制信号量之间的根本区别在于线程所有权.它有一个重大的后果,那就是重入的能力.可重入意味着已经拥有锁的线程可以再次获取它而不是死锁.如果你的类已经共享状态,你只想在所有方法中保护但是无法承担关于这些方法如何相互调用的永久假设,那么这是一个大问题; 或者通常在您的线程安全方案中发展的任何皮带和支撑特征.
信号量永远不可重入,Java监视器始终是可重入的. 如果你需要从许多代码位置锁定同一个对象,即使在单线程场景中,信号量也容易出现死锁 - 而信号量的这种限制只会在相对罕见的情况下带来任何好处,其中监视器无论如何都不是真正的选项.
线程所有权还大大降低了忘记锁定,忘记解锁或一个线程的活动掩盖另一个线程的活动的风险.相关的Java语法也存在显着的人体工程学差异.
还要注意这个问题 ; 虽然它使用了不同的术语,但更好的答案是将"互斥"理解为Java"监视器".
| 归档时间: |
|
| 查看次数: |
14674 次 |
| 最近记录: |