Java中 Synchronized和ReentrantLock

时间:2020-01-09 10:35:11  来源:igfitidea点击:

Java中获取互斥锁的传统方法是使用synced关键字,但是Java 5添加了新的锁实现,例如ReentrantLock和ReentrantReadWriteLock,它们提供了扩展的锁定操作功能。在这篇文章中,我们将看到Java中sync和ReentrantLock之间的区别。

Java中Synchronized和ReentrantLock的比较

1当我们使用synced关键字时,一旦输入同步方法或者块,将自动获取与该对象关联的隐式锁,并在同步方法或者块结束时自动释放该锁。

使用ReentrantLock,可以使用lock()和unlock()方法来获取和释放锁。

2)同步的使用更加严格。当获取多个锁时,所有锁的获取和释放都应该以块结构的方式进行,必须以相反的顺序释放它们,否则可能导致死锁。所有锁必须在获得它们的相同词汇范围内释放。

ReentrantLock的使用更加灵活。它允许在不同的范围内获取和释放锁,也允许以任意顺序获取和释放多个锁。

3 ReentrantLock在锁的顺序以及使用方法lock()和unlock()来获取和释放锁方面提供了灵活性,这使用户有责任在使用ReentrantLock时遵循如下所示的约定。

Lock l = new ReentrantLock();
 l.lock();
 try {
   // access the resource protected by this lock
 } finally {
   l.unlock();
 }

进入try块之前应获取锁定,并应在finally块中释放锁定。

在使用同步来保护关键部分时,没有这样的约定,即隐式完成获取和释放锁。

4ReentrantLock通过使用同步方法和语句提供了更多功能。

  • 使用tryLock()方法提供非阻塞尝试来获取锁,该方法仅在调用时另一个线程未持有该锁时才获取该锁。
  • 提供一种获取锁的功能,可以使用lockInterruptible()方法获取锁,除非当前线程被中断,否则该方法将获取锁。
  • 提供一种使用tryLock(long timeout,TimeUnit unit)方法获取可以超时的锁的功能,该方法可以在给定的等待时间内没有被另一个线程持有并且当前线程尚未中断的情况下获取该锁。

5ReentrantLock还提供了一种公平性选项,而同步方法和语句则不具备这种选项。如果使用synced关键字,则任何等待线程都可以获取该锁,这可能导致线程饥饿。
ReentrantLock类具有一个构造函数,该构造函数将布尔值作为参数。

ReentrantLock(boolean fair)

当布尔值作为true传递时,此锁应使用公平的排序策略。请注意,公平锁倾向于那些等待时间最长的线程。