使用锁定(java.util.concurrent.locks.Lock
)代替关键字synchronized
+方法wait()
和方法notify()
完全相同吗?
我可以使用锁(显式锁)而不是隐式锁(synchronized
)进行线程安全编程吗?
据我所知,我一直在使用隐式锁。我知道Lock
接口实现给出的优势,如方法:isLocked()
,getLockQueueLength()
,getHoldCount()
等等...但是仍然是旧学校方式({{ 1}}和wait()
)除了没有这些方法之外还有其他限制吗?
我也知道用(布尔公平)参数构造一个锁的可能性,该参数允许缺乏饥饿。
答案 0 :(得分:8)
是的,绝对可以使用java.util.concurrent.locks.Lock
编写线程安全程序。如果您发现java.util.concurrent.locks.Lock
ReentrantLock
内部实施的任何实施都使用了旧synchronized
块。
锁定实现提供了比使用同步方法和语句获得的更广泛的锁定操作。它们允许更灵活的结构,可能具有完全不同的属性,并且可能支持多个关联的Condition对象。
除了我的区别之外,synchronized
关键字自然内置了语言支持。这可能意味着JIT可以通过synchronised blocks
无法优化Locks
。例如它可以组合synchronized blocks
。 synchronized 最适合访问锁的少量线程,而Lock
可能最适合访问相同锁的大量线程。另外synchronized
阻止使得无保证关于等待进入它的线程被授予访问权限的顺序。
答案 1 :(得分:3)
锁和synchronized
块具有相同的语义,并从Java内存模型的角度提供相同的保证。主要区别在于Locks提供了更多控制(例如使用tryLock
或者要求锁定公平等),这样可以实现更灵活,更细粒度的锁定管理。
但是,当您不需要这些附加功能时,最好使用普通的synchronized
块,因为它可以减少出错的空间(例如,您不能“忘记”{{1} }它)。