《我要进大厂》系列之ReentrantLock与synchronized两种锁的区别

在大厂面试中,特别是第一轮技术面试中,锁是一个非常高频的主题,在JDK中主要提供了两种方式:JUC(JAVA并发框架)中的ReentrantLock与synchronized关键字。

那这两种有何区别呢?在实际工作中又如何选取呢?

ReentrantLock 实现 synchronized 的语义,提供多线程的同步阻塞语义,即我们通常意义上的同步锁,但 ReentrantLock 的使用更加灵活,提供了synchronized关键字不具备的功能特性。

1、可重入性

ReentrantLock 与 synchronized 都是允许重入的。

用一段的代码说明下锁的可重入语义:
在这里插入图片描述
即一个线程在获取了一把锁后,还可以继续申请获取。

2、ReentrantLock支持公平/非公平锁

在这里插入图片描述
NonFairSync 非公平锁:在申请锁时首先尝试去抢占锁,如果未成功获取锁后才无奈进入排队队列。

FairSync 公平锁:在申请锁时会进入锁排队队列,中规中矩的等待锁。

例如当前有3个线程在排队等待锁,持有锁的线程执行完临界区代码后释放锁时,正好又来了一个新的线程也需要获取锁,如果是公平锁,则需要等待前面3个线程获取锁后才能获取锁。如果是非公平锁,他会尝试与锁排队队列总的其他线程一起竞争锁,有可能直接获取锁就执行,这对已在队列中排队的线程就显得不那么公平了。

通常情况下,非公平锁涉及更少的线程切换开销,整体性能比公平锁要高

3、ReentrantLock支持锁等待超时

ReentrantLock 在申请锁时支持设置超时时间,即在多久未成功获得锁时被自动唤醒,可通过 tryLock 方法实现。
在这里插入图片描述
该方法获取锁后会立即返回,否则会阻塞,直到超时,返回true时表示成功获取锁。

4、ReentrantLock 支持中断

ReentrantLock 提供了 lockInterruptibly() 方法实现可中断的锁申请,即一个线程在竞争锁而陷入阻塞状态后,可以由另个一个线程来中断这个线程,从而放弃锁申请。

其实现是通过LockSupport的park()方法。
在这里插入图片描述
LockSupport 的 park 方法能响应中断,如果线程被中断,该方法能停止阻塞而被返回,但不会抛出 InterruptedException

5、ReentrantLock 支持灵活的监控

在这里插入图片描述
ReentrantLock提供了众多的方法,对开发监控锁相关的应用程序有莫大的帮助。

6、总结

ReentrantLock与synchronized具有相同的同步阻塞语义,从jdk1.6以后,两者的性能相差无几,如果没有特殊的使用需求,直接使用synchronized即可,因为锁的内部存储结构由虚拟机负责,使用简单。


见字如面,我是威哥,一个从普通二本院校毕业,从未曾接触分布式、微服务、高并发到通过技术分享实现职场蜕变,成长为RocketMQ社区优秀布道师、大厂资深架构师,出版《RocketMQ技术内幕》一书,在CSDN中记录了我的成长历程,欢迎大家关注,私信,一起交流进步。

分享笔者一个硬核的RocketMQ电子书:
在这里插入图片描述
获取方式:微信搜索【中间件兴趣圈】,回复RMQPDF即可获取。

猜你喜欢

转载自blog.csdn.net/prestigeding/article/details/115271726