与信号灯或显示器同步更好吗?与信号灯或显示器同步更好吗?
回答
“更好”取决于上下文。根据詹姆斯麦克帕兰的说法,他们“同样强大”。我强烈建议观看his blog for a discussion on the differences。
这里是一个快速指南,我发现:
信号灯
- 可以在程序中任何地方使用,但不应该在一个显示器中使用
Wait()
并不总是阻止调用者(即,当信号量计数器大于零时)。Signal()
要么释放阻塞的线程(如果有的话),要么增加信号量计数器。- 如果
Signal()
释放阻塞的线程,则调用者和释放的线程都会继续。
条件变量
- 只能在监视器
Wait()
始终阻塞调用者使用。Signal()
要么释放阻塞的线程,如果有的话,或者信号丢失,就好像它从不发生。- 如果
Signal()
释放阻塞的线程,调用者生成监视器(Hoare类型)或继续(Mesa类型)。只有一个调用者或已发布的线程可以继续,但不能同时有两个。
从这个信息:http://www.cs.mtu.edu/~shene/NSF-3/e-Book/MONITOR/sema-vs-monitor.html
一些有用的资源:
首先,你甲肝e决定使用哪个JDK。 仅提供线程的第一个Java版本。自Java Tiger(5.0)以来,引入了新类来处理并发。 特别提供了一个完整的包,其中包括java.util.concurrent。
根据我的经验,我发现显示器更好,因为它们让代码更干净。而且,使用它们让代码更易于理解。他们通过实现锁接口的类通常实现的:由JDK提供的最有名的实现是的ReentrantLock类,它定义了一个普通的锁,以及特定的的ReentrantReadWriteLock类,它提供写和/或读取锁定。
因此,使用锁来启用/禁用对共享对象(例如对象列表)的访问。
甲旗语对象是同步的用于协调和控制线(有在最新的JDK提供,如旗语,的CyclicBarrier,CountdownLatch,和器类许多同步器)。例如,使用Semaphore,您可以将固定数量的标记释放到您的线程池中,并决定可以同时执行的操作数量。就我个人而言,我不喜欢这种方法,因为与Futures and Locks一起使用线程池可以以更清洁和更安全的方式获得相同的结果。
在本书中可以找到更多信息:“Java Concurrency in Practice”,在本IBM教程中:“Concurrency in JDK 5.0”。一些更好的例子可以找到here。
确认,通过显示器我们的意思是旧的关键字。
第一个问题,你需要你的锁有柜台吗?
- 信号量可以有一个计数器大于一个。如果你需要保护N资源,信号量是最好的。轻松的决定。
- 如果您正在保护单个资源,这是信号量(1)和监视器同等适用的有趣情况。
J2SE 5.0 concurrency article在此给出了很好的建议。显示器是有限的,因为:
- 没有办法从企图后退,以获取已持有的锁,或等待一段指定的时间后放弃或取消后锁定尝试一个中断。
- 没有办法改变锁的语义,例如,在重入,读写保护或公平性方面。
- 同步在方法和块中完成,因此限制使用严格的块结构锁定。换句话说,你不能在一种方法中获得锁,并在另一个方法中释放它。。
因此,如果这些项目中的任何一项对您很重要 - 在超时后退出是一个很好的例子 - 那么请使用Semaphore。如果没有,显示器是好的。
如果你有头痛极小化后,更喜欢信号灯监视器(块/方法),无论你觉得锁定原语的真正的选择。 忽略关于信号量灵活性的学术讨论。你是在可靠性之后,而不是可配置性,不是吗?
人们经常声称监视器和信号灯是等价的(可以互相模拟),但是这种等价性比sometimes expected更加抽象和有用。 任何人谁可以正确模拟一个与另一个不需要任何回答这个问题了。
很明显,在允许同时进入块的线程数大于1的情况下,信号量是唯一的实际选择。因此,显示器的真正竞争对手是二进制信号量,即那些初始化为1的计数器,并且还包括那些您期望执行锁定以最终解锁信号量的线程的计算器。所以让我们仔细看看这些情况。
监视器和二进制信号量之间的根本区别是线程所有权。它具有很大的后果,那就是重入的能力。重入意味着已经拥有锁的线程可以重新获取它,而不是死锁。如果你的班级共享了你只是想用所有方法保护的状态,但却无法对这些方法如何相互呼叫提供永久的假设,这是一件大事。或者随着你的线程安全计划中发展的任何皮带和支架特征。
信号量永远不会重入,Java监视器总是可重入的。即使在单线程场景中,如果您需要锁定多个代码位置中的同一对象semaphores are prone to deadlocks,并且信号量的局限性只会在相对罕见的情况下带来任何好处,无论如何监视器并不是真正的选项。
线程所有权还大大降低了忘记锁定,忘记解锁或一个线程的活动掩盖另一个线程的活动的风险。在关联的Java语法中也存在显着的人机工程学差异。
另请注意this question;虽然它使用了不同的术语,但更好的答案在这里理解为“互斥体”,意味着Java“监视器”。
- 1. 与信号灯同步
- 2. 异步或同步加载更好?
- 3. 从同步任务调用方法的异步或同步版本更好吗?
- 4. 多进程同步 - 比信号量更好的选择?
- 5. 与信号量共享内存同步
- 6. 简单的与C信号同步
- 7. 在显示器上同步
- 8. 严格的使用2个信号灯的N进程同步
- 9. CMU:信号灯
- 10. 在信号灯
- 11. OpenCL - 同步和信号?
- 12. 线程同步和信号
- 13. 处理同步信号
- 14. 使用信号同步
- 15. django信号:同步问题?
- 16. 信号量和同步
- 17. bxSlider当前幻灯片编号显示/总幻灯片显示
- 18. Mutex替代进程同步/信号与异步支持?
- 19. TDBGrid - 同步或显示问题
- 20. 隐藏/显示元素或追加元素会更好吗?
- 21. 使用信号灯
- 22. 了解信号灯
- 23. 信号灯死锁
- 24. 了解信号灯
- 25. 使用if或switch语句更改交通信号灯
- 26. C:信号处理和信号灯
- 27. IPCS不显示我的共享内存和信号灯
- 28. 异步同步执行更好?
- 29. Android模拟器不显示信号条
- 30. jAlert不显示与jQuery ajax同步
你需要同步的具体问题是什么? – irreputable 2011-02-22 21:08:14
一般来说 – 2011-02-22 21:12:04
一般要么比另一个好,同时也差一些。 – irreputable 2011-02-22 21:14:06