java 可重入锁ReentrantLock的介绍
一个小例子帮助理解(我们常用的synchronized也是可重入锁)
话说从前有一个村子,在这个村子中有一口水井,家家户户都需要到这口井里打水喝。由于井水有限,大家只能依次打水。为了实现家家有水喝,户户有水用的目标,村长绞尽脑汁,最终想出了一个比较合理的方案。
首先,在水井边上安排一个看井人,负责维持秩序。
然后,打水时,以家庭为单位,哪个家庭任何人先到井边,就可以先打水,而且如果一个家庭占到了打水权,其家人这时候过来打水不用排队。而那些没有抢占到打水权的人,一个一个挨着在井边排成一队,先到的排在前面。
最后,打水的人打完水以后就告诉看井人,看井人就让等待的队伍中的最前面一个去打水。
这样一来,大家都能打到水,也保证了相对的公平。这就是公平锁的基本思路。
随着时间的推移,村民发现每次去打水的时候都需要排队,想着每次排队都浪费时间,于是就把水桶放在井边代替,自己则溜回家去了。这样一搞,可把看井人累坏,经常往村民家里跑,让他们来打水。于是聪明的看井人想出了一个对策,如果有人打完水后,刚好又有其它人来打水,就直接让这个新来的人上去打水,不用到队伍末尾去排队等候。
这种方式虽然看上去不公平,但是他节省了资源,提高了打水的性能,这就是非公平锁的基本思路。
打水的小故事在java中的应用
Java中可重入锁-ReentrantLock基本上就是按照上面的思路来实现的,我们来对给他们做一个简单的对比。
一次只有一个人能打水 锁需要保证多线程的同步。
必须严格按照排队顺序打水 ReentrantLock提供的公平锁功能。
来得早不如来得巧 ReentrantLock提供的非公平锁功能。
有家人正在打水的时候就不需要排队 ReentrantLock的可重入特性。
那么可重入锁又是怎样实现上面那些特性的呢?
java可重入锁-ReentrantLock实现细节
首先我们从上面的故事入手,看看ReentrantLock中的各个角色都是怎么样的。
打水权 volatile int state
打水者 线程、Thread
打水队伍 双向链表Node
获取锁的时候,公平锁的整个工作流程就如下图所示:

可重入公平锁获取流程
在获取锁的时候,如果当前线程之前已经获取到了锁,就会把state加1,在释放锁的时候会先减1,这样就保证了同一个锁可以被同一个线程获取多次,而不会出现死锁的情况。这就是ReentrantLock的可重入性。
对于非公平锁而言,调用lock方法后,会先尝试抢占锁,在各种判断的时候会先忽略等待队列,如果锁可用,就会直接抢占使用。
释放锁的时候,整个工作流程如下图:

可重入锁释放过程
本文为转载:https://baijiahao.baidu.com/s?id=1594800969528243663&wfr=spider&for=pc
参考:https://blog.csdn.net/yanyan19880509/article/details/52345422
java 可重入锁ReentrantLock的介绍的更多相关文章
- 轻松学习java可重入锁(ReentrantLock)的实现原理
转载自https://blog.csdn.net/yanyan19880509/article/details/52345422,(做了一些补充) 前言 相信学过java的人都知道 synchroni ...
- 轻松学习java可重入锁(ReentrantLock)的实现原理(转 图解)
前言 相信学过java的人都知道 synchronized 这个关键词,也知道它用于控制多线程对并发资源的安全访问,兴许,你还用过Lock相关的功能,但你可能从来没有想过java中的锁底层的机制是怎么 ...
- java可重入锁reentrantlock
public class ReentrantDemo { //重入锁 保护临界区资源count,确保多线程对count操作的安全性 /*public static ReentrantLock rtlo ...
- Java 重入锁 ReentrantLock 原理分析
1.简介 可重入锁ReentrantLock自 JDK 1.5 被引入,功能上与synchronized关键字类似.所谓的可重入是指,线程可对同一把锁进行重复加锁,而不会被阻塞住,这样可避免死锁的产生 ...
- Java 显示锁 之 重入锁 ReentrantLock(七)
ReentrantLock 重入锁简介 重入锁 ReentrantLock,顾名思义,就是支持同一个线程对资源的重复加锁.另外,该锁还支持获取锁时的公平与非公平性的选择. 重入锁 ReentrantL ...
- synchronized关键字,Lock接口以及可重入锁ReentrantLock
多线程环境下,必须考虑线程同步的问题,这是因为多个线程同时访问变量或者资源时会有线程争用,比如A线程读取了一个变量,B线程也读取了这个变量,然后他们同时对这个变量做了修改,写回到内存中,由于是同时做修 ...
- 17_重入锁ReentrantLock
[概述] 重入锁可以完全代替synchronized关键字. 与synchronized相比,重入锁ReentrantLock有着显示的操作过程,即开发人员必须手动指定何时加锁,何时释放锁,所以重入锁 ...
- Java不可重入锁和可重入锁的简单理解
基础知识 Java多线程的wait()方法和notify()方法 这两个方法是成对出现和使用的,要执行这两个方法,有一个前提就是,当前线程必须获其对象的monitor(俗称“锁”),否则会抛出Ille ...
- Java中可重入锁ReentrantLock原理剖析
本文由码农网 – 吴极心原创,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划! 一. 概述 本文首先介绍Lock接口.ReentrantLock的类层次结构以及锁功能模板类AbstractQue ...
随机推荐
- 解决“chrome adobe flash player不是最新版本”的方法
chrome地址栏输入chrome://components 更新flash后,重启chrome即可,可能需要搭梯子才能更新.
- pytest.7.常见套路
From: http://www.testclass.net/pytest/common_useage/ 在使用pytest的时候,下面这些问题我们可能会经常遇到,这里给出官方的解决方案,按照套路来执 ...
- Survival Analysis
code{white-space: pre;} Survival Analysis Zhu Lin 2017-3-18 What is Survival Analysis Survival analy ...
- 廖雪峰Java4反射与泛型-2注解-2定义注解
1.定义注解 使用@interface定义注解Annotation 注解的参数类似无参数方法 可以设定一个默认值(推荐) 把最常用的参数命名为value(推荐) 2.元注解 2.1Target使用方式 ...
- js读取iframe里的元素
父层 <div id="SubStepNav" class="SubStepNav"> <iframe src="aaa.html& ...
- hashMap为啥初始化容量为2的次幂
原文 https://blog.csdn.net/sd_csdn_scy/article/details/57083619hashMap源码获取元素的位置: static int indexFor(i ...
- shell 发送所有内容到会话
在shell当中 工具 发送键输入到所有会话 会有新的发现
- sklearn不同数量的训练集在测试集上的表现的曲线刻画
def plot_learning_curve(estimator,X,y,cv=5,train_sizes=[0.1,0.3,0.5,0.7,0.8,0.9]): """ ...
- hive spark版本对应关系
查看hive source下面的pom.xml,可以找到官方默认发布的hive版本对应的spark版本,在实际部署的时候,最好按照这个版本关系来,这样出现兼容问题的概率相对较小. 下面面列出一部分对应 ...
- 利用WordPress REST API 开发微信小程序从入门到放弃
自从我发布并开源WordPress版微信小程序以来,很多WordPress网站的站长问有关程序开发的问题,其实在文章:<用微信小程序连接WordPress网站>讲述过一些基本的要点,不过仍 ...