我在Java中使用了synchronized
关键字和重入锁,但我不明白它们之间的区别,或者哪种情况适合于特定情况。
我如何决定何时使用synchronized
以及何时应使用可重入锁?
答案 0 :(得分:23)
具有相同基本行为的重入互斥锁定 语义作为使用synchronized访问的隐式监视器锁 方法和陈述,但具有扩展功能。
扩展功能包括:
“[fair]锁定有利于授予对等待时间最长的线程的访问权限。否则此锁定不保证任何特定的访问顺序。”
重入锁的缺点是:
synchronized
关键字可以放在方法定义中,避免了需要减少嵌套的块。<强>摘要强>
synchronized
关键字在语法上更好,但是重入锁具有更多功能。
答案 1 :(得分:1)
该网站明确提到了Java中ReentrantLock和synchronized关键字之间的区别。我只是从那里复制粘贴。
1)ReentrantLock和synchronized关键字之间的另一个显着差异是公平性。 synchronized关键字不支持公平性。任何线程一旦释放就可以获得锁定,不能指定首选项,另一方面,您可以通过指定公平属性使ReentrantLock公平,同时创建ReentrantLock实例。在争用的情况下,公平属性为最长的等待线程提供锁定。
2)synchronized和Reentrant锁之间的第二个区别是tryLock()方法。 ReentrantLock提供了方便的tryLock()方法,只有当它可用或不被任何其他线程持有时才获取锁。这减少了在Java应用程序中等待锁定的线程阻塞。
3)Java中ReentrantLock和synchronized关键字之间的另一个值得注意的区别是,在等待Lock时中断Thread的能力。在synchronized关键字的情况下,可以无限期地阻塞线程等待锁定,并且无法控制该线程。 ReentrantLock提供了一个名为lockInterruptibly()的方法,可用于在等待锁定时中断线程。类似地,如果在某段时间内锁定不可用,则带超时的tryLock()可用于超时。
4)ReentrantLock还提供了方便的方法来获取等待锁定的所有线程的列表。
答案 2 :(得分:0)
我一直认为同步是“阻力最小的黑客”。它只是工作,大多数人都了解它是如何工作的,但它有一些弱点,可能会影响你的设计在严重的并发。其中最重要的是任何客户端都可以直接访问对象的同步锁,这意味着如果他们抓住它并持有其他客户端则不能。换句话说,默认同步实现的锁定有效地“发布”了对象的内部锁定机制。育。它就像为自己造成的自我拒绝服务一样。
如果你在你的类内部进行重入锁定(或者只是不使用synchronized,而是在你想要同步的构造函数中执行某些内部对象上的同步),则删除此方 - 发布内部锁定机制的效果,增加了复杂性,您必须记住在课程发展过程中应用此内部同步的位置。