Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >synchronized 和 ReentrantLock 的区别

synchronized 和 ReentrantLock 的区别

作者头像
黑洞代码
发布于 2021-03-01 09:12:38
发布于 2021-03-01 09:12:38
3550
举报

是否可重入

“可重入锁” 指的是自己可以再次获取自己的内部锁。比如一个线程获得了某个对象的锁,此时这个对象锁还没有释放,当其再次想要获取这个对象的锁的时候还是可以获取的。如果不可锁重入的话,就会造成死锁。同一个线程每次获取锁,锁的计数器都自增 1,所以要等到锁的计数器下降为 0 时才能释放锁。

synchronized 和 ReentrantLock都是可重入锁。

实现方式

synchronized 依赖于 JVM 而 ReentrantLock 依赖于 API

synchronized 是依赖于 JVM 实现的,前面我们也讲到了 虚拟机团队在 JDK1.6 为 synchronized 关键字进行了很多优化,但是这些优化都是在虚拟机层面实现的,并没有直接暴露给我们。ReentrantLock 是 JDK 层面实现的(也就是 API 层面,需要 lock() 和 unlock() 方法配合 try/finally 语句块来完成),所以我们可以通过查看它的源代码,来看它是如何实现的。

功能

ReentrantLock 比 synchronized 增加了一些高级功能。

相比synchronized,ReentrantLock增加了一些高级功能。主要来说主要有三点:

  1. 等待可中断 : ReentrantLock提供了一种能够中断等待锁的线程的机制,通过 lock.lockInterruptibly() 来实现这个机制。也就是说正在等待的线程可以选择放弃等待,改为处理其他事情。
  2. 可实现公平锁 : ReentrantLock可以指定是公平锁还是非公平锁。而synchronized只能是非公平锁。所谓的公平锁就是先等待的线程先获得锁。ReentrantLock默认情况是非公平的,可以通过 ReentrantLock类的ReentrantLock(boolean fair)构造方法来制定是否是公平的。
  3. 可实现选择性通知(锁可以绑定多个条件): synchronized关键字与wait()和notify()/notifyAll()方法相结合可以实现等待/通知机制。ReentrantLock类当然也可以实现,但是需要借助于Condition接口与newCondition()方法。

Condition是 JDK1.5 之后才有的,它具有很好的灵活性,比如可以实现多路通知功能也就是在一个Lock对象中可以创建多个Condition实例(即对象监视器),线程对象可以注册在指定的Condition中,从而可以有选择性的进行线程通知,在调度线程上更加灵活。在使用notify()/notifyAll()方法进行通知时,被通知的线程是由 JVM 选择的,用ReentrantLock类结合Condition实例可以实现“选择性通知” ,这个功能非常重要,而且是 Condition 接口默认提供的。而synchronized关键字就相当于整个 Lock 对象中只有一个Condition实例,所有的线程都注册在它一个身上。如果执行notifyAll()方法的话就会通知所有处于等待状态的线程这样会造成很大的效率问题,而Condition实例的signalAll()方法 只会唤醒注册在该Condition实例中的所有等待线程。

如果你想使用上述功能,那么选择 ReentrantLock 是一个不错的选择。性能已不是单纯的选择标准。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-02-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 落叶飞翔的蜗牛 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
大厂高频面试题:ReentrantLock 与 synchronized异同点对比
在过去的博文中我们学习了ReentrantLock 与 synchronized这两种Java并发使用频率最高的同步锁,在很多大厂面试题中有个经典考题:
JavaBuild
2024/05/27
2470
大厂高频面试题:ReentrantLock 与 synchronized异同点对比
值得保存的 synchronized 关键字总结
本文是对 synchronized 关键字使用、底层原理、JDK1.6之后的底层优化以及和ReenTrantLock对比做的总结。如果没有学过 synchronized 关键字使用的话,阅读起来可能比较费力。两篇比较基础的讲解 synchronized 关键字的文章:
用户2164320
2018/09/07
4010
synchronized 与多线程的哪些关系
JVM 实现的 synchronized JDK 实现的 ReentrantLock
BUG弄潮儿
2022/06/30
2770
synchronized 与多线程的哪些关系
【JUC基础】05. Synchronized和ReentrantLock
前面两篇中分别讲了Synchronized和ReentrantLock。两种方式都能实现同步锁,且也都能解决多线程的并发问题。那么这两个有什么区别呢? 这个也是一个高频的面经题。
有一只柴犬
2024/01/25
1630
【JUC基础】05. Synchronized和ReentrantLock
并发编程-19AQS同步组件之重入锁ReentrantLock、 读写锁ReentrantReadWriteLock、Condition
重入锁ReentrantLock,顾名思义,就是支持重进入的锁,它表示该锁能够支持一个线程对 资源的重复加锁,而不会造成自己阻塞自己。
小小工匠
2021/08/17
2900
Synchronized 与 ReentrantLock 的区别!
今天现来深入了解下 Synchronized 与 ReentrantLock 的区别!
Java技术栈
2019/07/08
1.2K0
Java并发基石ReentrantLock:深入解读其原理与实现
ReentrantLock,也被称为“可重入锁”,是一个同步工具类,在java.util.concurrent.locks包下。这种锁的一个重要特点是,它允许一个线程多次获取同一个锁而不会产生死锁。这与synchronized关键字提供的锁定机制非常相似,但ReentrantLock提供了更高的扩展性。
公众号:码到三十五
2024/03/24
5.1K0
Java并发基石ReentrantLock:深入解读其原理与实现
【Java面试总结】多线程
进程是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个即是一个进程从创建、运行到消亡的过程。
Rochester
2020/09/07
9160
【Java面试总结】多线程
面试Java基础问题汇总 part2
Synchronized关键字同步语句块使用的是monitorenter和monitorexit指令,其中monitorenter指令指向同步代码块的开始位置,monitorexit指令指示结束位置。
Steve Wang
2020/09/17
4540
AQS扩展与ReentrantLock实现
在ReentrantLock内部实现了公平锁(FairSync)和非公平锁(NonfairSync)两套锁实现, 两者区别可以参考AQS介绍.
一个架构师
2022/06/20
2610
AQS扩展与ReentrantLock实现
一文带你读懂JDK源码:synchronized
Java提供的常用同步手段之一就是sychronized关键字,synchronized 是利用锁的机制来实现同步的。
后台技术汇
2022/05/28
2920
一文带你读懂JDK源码:synchronized
Java Concurrent ReentrantLock(Java 10)
Reentrant是一种可重入锁,是一种递归无阻塞的同步机制。实现了和synchronized类似的同步策略。与synchronized配合使用的wait、notify、notifyall等函数,由Codition负责提供,这个后续另外会说。
邹志全
2019/07/31
3970
Java 多线程 (Part2: Java线程 Lock锁)
悲观锁: 一定会出现多线程场景,先加锁,Synchronized 和 Lock 都是悲观锁 (适合 write多)
JiahuiZhu1998
2022/12/30
4380
Java并发编程(六)---lock
前面几篇文章,我们学习了synchronized的相关知识,以及死锁的发生条件以及避免的方式,其中有一种破坏死锁的方式就是破坏不可抢占条件,通过synchronzied不能实现的,因为synchronized在申请资源的时候,如果申请不到就只能进入阻塞状态,啥都干不了,也不能中断。所以只能通过本期的主角lock 来处理。
码农飞哥
2021/08/18
2830
JDK源码分析-ReentrantLock
在 JDK 1.5 以前,锁的实现只能用 synchronized 关键字;1.5 开始提供了 ReentrantLock,它是 API 层面的锁。先看下 ReentrantLock 的类签名以及如何使用:
WriteOnRead
2019/08/16
2490
可重入锁的意思上边这个代码 a b都用到锁 执行b的时候不会因为a获取锁后还没释放而无法获得锁不能执行代码 a获得锁后 执行b后不用再获取锁 直接执行就可以
周杰伦本人
2022/10/25
2740
JUC 多线程知识杂集
synchronized是关键字,属于JVM层面,monitorenter(底层是通过monitor对象来完成,其实wait/notify等方法也依赖于monitor对象只有在同步块或者方法中才能调用wait/notify等方法)
万能青年
2019/08/30
3100
JAVA并发万字长文从ReentrantLock到juc框架
ReentrantLock 是 Java 中的可重入锁,它实现了 Lock 接口,与 synchronized 相比,ReentrantLock提供了更强大和灵活的锁机制。
青山师
2023/05/02
2510
JAVA并发万字长文从ReentrantLock到juc框架
Synchronized和ReentryLock有什么区别?用新Lock有什么好处?
二,使用方法 synchronized 不需要用户去手动释放锁,当synchronized代码执行完后系统会自动让线程释放对锁的占用 ReentrantLock则需要用户去手动释放锁若没有主动释放锁,就有可能导致出现死锁现象。需要Lock()unLock()方法配合try/finally语句块来完成。
名字是乱打的
2022/05/13
7230
Java的ReentrantLock详解
ReentrantLock 是 Java 并发包(java.util.concurrent.locks)中的一个可重入锁实现,它提供了比 synchronized 关键字更灵活、功能更丰富的线程同步机制。ReentrantLock类内部总共存在Sync、NonfairSync、FairSync三个类,NonfairSync(非公平锁)与FairSync(公平锁)类继承自Sync类,Sync类继承自AbstractQueuedSynchronizer抽象类。
tt天
2024/04/23
2180
Java的ReentrantLock详解
相关推荐
大厂高频面试题:ReentrantLock 与 synchronized异同点对比
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档