第15讲 | synchronized和ReentrantLock有什么区别呢?
杨晓峰
该思维导图由 AI 生成,仅供参考
从今天开始,我们将进入 Java 并发学习阶段。软件并发已经成为现代软件开发的基础能力,而 Java 精心设计的高效并发机制,正是构建大规模应用的基础之一,所以考察并发基本功也成为各个公司面试 Java 工程师的必选项。
今天我要问你的问题是, synchronized 和 ReentrantLock 有什么区别?有人说 synchronized 最慢,这话靠谱吗?
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
本文深入讨论了Java并发编程中的synchronized和ReentrantLock的区别及使用场景。首先介绍了线程安全的概念和保证线程安全的两种办法:封装和不可变。然后通过代码示例展示了原子性需求的体现,并对synchronized和ReentrantLock的底层实现进行了比较。文章还介绍了ReentrantLock的再入性和公平性设置,以及与synchronized相比的优势,如带超时的获取锁尝试、判断是否有线程在排队等待获取锁等。此外,还详细介绍了条件变量的使用,以及ReentrantLock在高竞争情况下的性能优势。总的来说,本文内容涵盖了线程安全、synchronized和ReentrantLock的基本概念,以及它们的使用方法和性能比较,对于想要深入了解并发编程的读者具有重要意义。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Java 核心技术面试精讲》,新⼈⾸单¥59
《Java 核心技术面试精讲》,新⼈⾸单¥59
立即购买
登录 后留言
全部留言(74)
- 最新
- 精选
- 冬青树一直在研究JUC方面的。所有的Lock都是基于AQS来实现了。AQS和Condition各自维护了不同的队列,在使用lock和condition的时候,其实就是两个队列的互相移动。如果我们想自定义一个同步器,可以实现AQS。它提供了获取共享锁和互斥锁的方式,都是基于对state操作而言的。ReentranLock这个是可重入的。其实要弄明白它为啥可重入的呢,咋实现的呢。其实它内部自定义了同步器Sync,这个又实现了AQS,同时又实现了AOS,而后者就提供了一种互斥锁持有的方式。其实就是每次获取锁的时候,看下当前维护的那个线程和当前请求的线程是否一样,一样就可重入了。
作者回复: 正解
2018-06-079134 - Jerry银银先说说点学习感受: 并发领域的知识点很多也很散,并且知识点之间交错的。比如:synchronized,这个小小的关键字,能够彻底理解它,需要的知识储备有:基本使用场景、对锁的理解、对线程安全的理解、对同步语义的理解、对JMM的理解等等。有时候,一个知识点暂时做不到透彻理解,可能是正常的,需要再继续学习其它的知识点,等到一定时候,回过头来重新学习,会有一种柳暗花明又一村的感觉。我想,这也可能是老师提到的:并发领域相关知识的准备,需要点耐心。 再说说这篇专栏: 这篇专栏,在知识扩展部分,我觉得结构不是太清晰。我读了很多遍之后,还是有这种感觉:文章讲了很多东西,但是我却很难说出文章的主题。 为此,我自己总结了一下知识扩展部分的主线: 1. 进入并发领域,首先需要理解什么是线程安全,为什么会存在线程不安全,又为什么需要线程安全。这个知识点可参考《Java并发编程实践》,并且我也认为对于线程安全的讲解,这本书堪称权威; 2. 老师在讲解线程安全这个点的时候,顺其自然地使用了synchronized和ReentrantLock来保证线程安全(即:Java提供的锁机制)同时,老师也稍微讲解了一下synchronized和ReentrantLock的使用和区别; 3. 最后,老师举了一个ReentrantLock的典型使用场景:ArrayBlockingQueue。ArrayBlockingQueue使用ReentrantLock来实现加锁机制,保证队列的安全读取,并且使用Condition来实现队列阻塞的条件判断和读写端唤醒,特别提一句:具体的实现代码是相当的优雅!
作者回复: 非常感谢反馈
2019-02-01256 - BY要是早看到这篇文章,我上次面试就过了。。
作者回复: 加油
2018-06-07431 - 灰飞灰猪不会灰飞.烟灭ReentrantLock 加锁的时候通过cas算法,将线程对象放到一个双向链表中,然后每次取出链表中的头节点,看这个节点是否和当前线程相等。是否相等比较的是线程的ID。 老师我理解的对不对啊?
作者回复: 嗯,并发库里都是靠自己的synchronizer
2018-06-0719 - Kyle最近刚看完《Java 并发编程实战》,所以今天看这篇文章觉得丝毫不费力气。开始觉得,极客时间上老师讲的内容毕竟篇幅有限,更多的还是需要我们课后去深入钻研。希望老师以后讲完课也能够适当提供些参考书目,谢谢。
作者回复: 后面会对实现做些源码分析,其实还有各种不同的锁...
2018-06-0716 - Miaozhe杨老师,问个问题,看网上有说Condition的await和signal方法,等同于Object的wait和notify,看了一下源码,没有直接的关系。 ReentractLock是基于双向链表的对接和CAS实现的,感觉比Object增加了很多逻辑,怎么会比Synchronized效率高?有疑惑。
作者回复: 你看到的很对,如果从单个线程做的事来看,也许并没有优势,不管是空间还是时间,但ReentrantLock这种所谓cas,或者叫lock-free,方式的好处,在于高竞争情况的扩展性,而原来那种频繁的上下文切换则会导致吞吐量迅速下降
2018-06-12214 - 木瓜芒果杨老师,您好,synchronized在低竞争场景下可能优于retrantlock,这里的什么程度算是低竞争场景呢?
作者回复: 这个精确的标准我还真不知道,我觉得可以这么理解:如果大部分情况,每个线程都不需要真的获取锁,就是低竞争;反之,大部分都要获取锁才能正常工作,就是高竞争
2018-06-19313 - Daydayup我用过读写分离锁,读锁保证速度,写锁保证安全问题。再入锁还是挺好用的。老师写的很棒,学到不少知识。感谢
作者回复: 非常感谢
2018-06-139 - xinfangke老师 问你个问题 在spring中 如果标注一个方法的事务隔离级别为序列化 而数据库的隔离级别是默认的隔离级别 此时此方法中的更新 插入语句是如何执行的?能保证并发不出错吗
作者回复: 这个我没用过,哪位读者熟悉?
2018-06-0836 - Neil可以理解为synchronized是悲观锁 另一个是乐观锁
作者回复: 基本如此,乐观、悲观是两种不同的处理策略
2019-01-0724
收起评论