Lock和Synchronized的区别

136 阅读2分钟

这两个锁大部分人都能知道一二。接下来从几个方面进行说明。

补充下,lock的实现类ReentrantLock和Synchronized都是可重入锁。

1.底层实现不同

Synchronized是关键字,底层是由c++进行实现的,是JVM层面的锁。而lock是接口,是由java代码实现的,是调用对应的方法来进行加锁,是api层面的锁

synchronized底层是基于monitor对象来实现加锁和释放锁的。这里解释下什么是monitor:monitor中有主要的三个属性,waitset,entryset,owner。 一个是等待队列,一个是阻塞队列,一个是当前拥有锁的线程。这也是为什么wait和notify的调用要在syn块儿中。因为只有在同步代码块或者是同步方法中,JVM才会调用 monitor 对象。

而lock是基于aqs对api的调用,进行加锁。

2.使用方法不同

synchronized是隐式锁,lock是显示锁。

隐式锁就是,上锁和释放锁不需要我们手动进行

显示锁就需要我们手动进行上锁和释放锁

在使用sync关键字的时候,程序能够自动获取锁和释放锁。那是因为当sync代码块执行完成之后,系统会自动的让程序释放占用的锁。Sync是由系统维护的,如果非逻辑问题的话,是不会出现死锁的。

在使用lock锁时,我们需要手动进行上锁和释放锁,否则可能会造成死锁现象,上锁:lock()。释放锁:unlock()

3.是否可以中断锁的等待。

synchronized对于锁不可以进行中断操作。

lock可以对锁的等待进行终端操作。

1.使用**tryLock(long timeout ,timeUnit unit)**方法设置超时时间,如果在这个时间内都还没获得锁,就不会在这死等,就会执行下面的代码。

2.可以使用lockInterruptibly(),可以对该线程进行打断操作,调用interrupt()方法。

4.加锁的时候是否公平

synchronized是非公平锁。

lock是可公平锁,也可是非公平锁。默认是非公平。可以通过在创建锁对象时,在构造器中加入boolean参数,true为公平锁,false为非公平锁。

5.条件变量(等待队列)和阻塞队列

synchronized中的monitor只有一个等待队列,和一个阻塞队列。要么随机唤醒一个,要么全部唤醒,唤醒不准确

lock可以通过newCondition设置多个条件变量,可以精确的进行唤醒。也只有一个阻塞队列。

本文使用 文章同步助手 同步