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

我在Java中使用了synchronized关键字和可重入锁,但我不明白它们是如何不同的,或者哪种适用于给定的情况。

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

ReentrantLock是:

可重入互斥锁具有与使用同步方法和语句访问的隐式监视器锁相同的基本行为和语义,但具有扩展function。

扩展function包括:

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

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

  3. 能够检查是否正在进行锁定。
  4. 获取等待锁定的线程列表的能力。

重入锁的缺点是:

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

概要

synchronized关键字在语法上更好,但是Reentrant锁具有更多function。

该网站明确提到了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还提供了方便的方法来获取等待锁定的所有线程的List。

我一直认为同步是“阻力最小的黑客”。 它只是工作,大多数人都了解它是如何工作的,但它有一些弱点,可能会影响你的设计在严重的并发。 其中最重要的是任何客户端都可以直接访问对象的同步锁,这意味着如果他们抓住并保留其他客户端则不能。 换句话说,默认同步实现的锁定有效地“发布”了对象的内部锁定机制。 育。 它就像为自己造成的自我拒绝服务一样。

如果你在你的类内部使用reentrant锁(或者只是不使用synchronized,而是在你想要同步的构造函数中执行某些内部对象上的同步),则会消除发布的这种副作用您的内部锁定机制,增加了复杂性,您必须记住在您的类演变时应用此内部同步的位置。