Java并发编程锁系列之ReentrantLock对象总结
Java并发编程锁系列之ReentrantLock对象总结
在Java并发编程中,根据不同维度来区分锁的话,锁可以分为十五种。ReentranckLock就是其中的多个分类。
本文主要内容:重入锁理解;重入锁代码演示; ReentranckLock的总结
本篇是《凯哥(凯哥Java:kagejava)并发编程学习》系列之《Lock系列》教程的第四篇:《Java并发包下锁学习第六篇:ReentranckLock的总结》。
我们先来看看内部结构:
ReentranckLock内部有三个内部类,分别是:
Sync:继承了AbstractQueuedSynchronizer(AQS)同步器的内部类,来实现同步机制的;
FairSync:公平锁对象;
NonfairSync:非公平锁对象。
关于公平锁与非公平锁详细介绍文章见:《Java并发编程锁之独占公平锁与非公平锁比较》和《Java并非锁之独占非公平锁理解》两篇文章。
再来看看对象名称:Reentranck的中文意思:再入、重入的意思。即该对象还是重入锁。
公平锁和非公平锁在获取锁的区别在于:
公平锁获取锁的时候,进入排队。源码如下图:
非公平锁线尝试插队,如果插队不成功再进行排队。源码如下图:
那么什么是重入锁呢?
重入锁(递归锁)可以理解为:同一个线程函数获得锁之后,内层递归函数依然能够获取到该锁对象的代码,也即,在同一个线程的外层方法访问的时候,获取到了锁,在进入内层方法后能够自动获取到锁。线程可以进入任何一个它已经拥有的锁所同步着的代码块。额,说的啥意思?每个中文都认识,但是组合在一起,就不知道啥意思了。
我们来举个生活中的例子:
在现实生活中,我们一般只需要带有自己大门的钥匙(当然,如果是合租的朋友还需要带着自己房间的钥匙)。当我们开了大门的钥匙,进入房间后,我们在去厨房或者是去卫生间的时候,不用在拿钥匙开厨房或者卫生间的门了吧。为啥呢?因为我们已经已经有大门的锁的钥匙并且已经进入到了房间了。厨房和卫生间已经在大门锁管理的范围内了。这种场景站在并发锁的角度来看的话:一同一个线程函数获得锁之后(你拿着钥匙打开了大门之后),内层递归函数依然能够获取到该锁对象的代码(进入房间后,房间内的厨房卫生间可以随便出入)。这样是不是就好理解了?
如果还是不理解的话,可以想想spring默认的事务传递方式。一个方法开启了事务,默认这个方法调用其他方法,也会使用这个事务。这样是不是就好理解了。
重入锁代码演示
先来看看,被线程操作的资源类:message对象
在message对象中,sendMsg使用了锁,sendEmail方法也使用了锁,而且在sendMesg方法中调用了sendEmail方法。
这个时候使用三个线程来操作:
运行结果:
我们从运行的结果中,可以看出,同一个线程操作了两个带有锁的方法。
说明ReentrantLock是可重入锁。
总结:
经过前面几篇及本篇的学习,我们可以对ReentrantLock(以下简称:RLock)得到如下总结
1:从线程是否需要对资源进行加锁方面来看的话,RLock是悲观锁;
2:从锁是否需要排队的公平性来区分的话,RLock的FairSync对象是公平锁而NonfairSync对象是非公平锁;
3:从多个线程能共享一把锁的角度来分的话RLock属于排他锁(独占式锁);
从锁是否重复获取角度来看,属于可重入锁
欢迎来聊~
本文来自博客园,作者:kaizi1992,转载请注明原文链接:https://www.cnblogs.com/kaigejava/p/12635905.html
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· 易语言 —— 开山篇
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 【全网最全教程】使用最强DeepSeekR1+联网的火山引擎,没有生成长度限制,DeepSeek本体