同步和重入锁定之间的区别?

时间:2012-01-30 23:39:12

标签: java thread-safety

我在Java中使用了synchronized关键字和重入锁,但我不明白它们之间的区别,或者哪种情况适合于特定情况。

我如何决定何时使用synchronized以及何时应使用可重入锁?

3 个答案:

答案 0 :(得分:23)

ReentrantLock是:

  

具有相同基本行为的重入互斥锁定   语义作为使用synchronized访问的隐式监视器锁   方法和陈述,但具有扩展功能。

扩展功能包括:

  1. 每个监视器有多个condition variable的能力。使用synchronized关键字的监视器只能有一个。这意味着可重入锁支持多个wait()/ notify()队列。
  2. 锁定fair的能力。同步块是不公平的。
      

    “[fair]锁定有利于授予对等待时间最长的线程的访问权限。否则此锁定不保证任何特定的访问顺序。”

  3. 检查锁定是否被保持的能力。
  4. 获取等待锁定的线程列表的能力。
  5. 重入锁的缺点是:

    1. 需要添加import语句。
    2. 需要在try / finally块中包装锁定获取。这使得它比synchronized关键字更难看。
    3. synchronized关键字可以放在方法定义中,避免了需要减少嵌套的块。
    4. <强>摘要

      synchronized关键字在语法上更好,但是重入锁具有更多功能。

答案 1 :(得分:1)

该网站明确提到了Java中ReentrantLock和synchronized关键字之间的区别。我只是从那里复制粘贴。

http://javarevisited.blogspot.in/2013/03/reentrantlock-example-in-java-synchronized-difference-vs-lock.html

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,而是在你想要同步的构造函数中执行某些内部对象上的同步),则删除此方 - 发布内部锁定机制的效果,增加了复杂性,您必须记住在课程发展过程中应用此内部同步的位置。