一个小例子帮助理解(我们常用的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的介绍的更多相关文章

  1. 轻松学习java可重入锁(ReentrantLock)的实现原理

    转载自https://blog.csdn.net/yanyan19880509/article/details/52345422,(做了一些补充) 前言 相信学过java的人都知道 synchroni ...

  2. 轻松学习java可重入锁(ReentrantLock)的实现原理(转 图解)

    前言 相信学过java的人都知道 synchronized 这个关键词,也知道它用于控制多线程对并发资源的安全访问,兴许,你还用过Lock相关的功能,但你可能从来没有想过java中的锁底层的机制是怎么 ...

  3. java可重入锁reentrantlock

    public class ReentrantDemo { //重入锁 保护临界区资源count,确保多线程对count操作的安全性 /*public static ReentrantLock rtlo ...

  4. Java 重入锁 ReentrantLock 原理分析

    1.简介 可重入锁ReentrantLock自 JDK 1.5 被引入,功能上与synchronized关键字类似.所谓的可重入是指,线程可对同一把锁进行重复加锁,而不会被阻塞住,这样可避免死锁的产生 ...

  5. Java 显示锁 之 重入锁 ReentrantLock(七)

    ReentrantLock 重入锁简介 重入锁 ReentrantLock,顾名思义,就是支持同一个线程对资源的重复加锁.另外,该锁还支持获取锁时的公平与非公平性的选择. 重入锁 ReentrantL ...

  6. synchronized关键字,Lock接口以及可重入锁ReentrantLock

    多线程环境下,必须考虑线程同步的问题,这是因为多个线程同时访问变量或者资源时会有线程争用,比如A线程读取了一个变量,B线程也读取了这个变量,然后他们同时对这个变量做了修改,写回到内存中,由于是同时做修 ...

  7. 17_重入锁ReentrantLock

    [概述] 重入锁可以完全代替synchronized关键字. 与synchronized相比,重入锁ReentrantLock有着显示的操作过程,即开发人员必须手动指定何时加锁,何时释放锁,所以重入锁 ...

  8. Java不可重入锁和可重入锁的简单理解

    基础知识 Java多线程的wait()方法和notify()方法 这两个方法是成对出现和使用的,要执行这两个方法,有一个前提就是,当前线程必须获其对象的monitor(俗称“锁”),否则会抛出Ille ...

  9. Java中可重入锁ReentrantLock原理剖析

    本文由码农网 – 吴极心原创,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划! 一. 概述 本文首先介绍Lock接口.ReentrantLock的类层次结构以及锁功能模板类AbstractQue ...

随机推荐

  1. HBase教程

    https://www.yiibai.com/hbase/ 自1970年以来,关系数据库用于数据存储和维护有关问题的解决方案.大数据的出现后,好多公司实现处理大数据并从中受益,并开始选择像 Hadoo ...

  2. List<T>Distinct 过滤

    public class TestDuplicateDefine : IEqualityComparer<student> { public bool Equals(student x, ...

  3. nvm环境配置

    安装nvm curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash nvm insta ...

  4. 【java】之常用四大线程池用法以及ThreadPoolExecutor详解

    为什么用线程池? 1.创建/销毁线程伴随着系统开销,过于频繁的创建/销毁线程,会很大程度上影响处-理效率2.线程并发数量过多,抢占系统资源从而导致阻塞3.对线程进行一些简单的管理 在Java中,线程池 ...

  5. JPanel添加键盘监听事件

    因为在自己的游戏需求中谢了要用键盘控制飞机的移动,所以用到键盘监听事件,但是使用了JPanel之后添加了键盘监听事件,按相应的方向键飞机并没有反应.但是如果是为JFrame的内容面板加则会有反应. 为 ...

  6. 基于element-ui的多选下拉框和tag标签的二次封装

    前言: 今年这大半年我主要负责公司的后台教务管理的开发,这个管理系统目前主要是给公司的内部人员去配置公司的核心项目(例如:熊猫小课)的所有数据,例如课程的配置.课程期数的配置.课程版本的配置.活动的配 ...

  7. Kubernetes DNS服务配置案例

    首先创建DNS服务的RC配置文件skydns-rc.yaml apiVersion: v1 kind: ReplicationController metadata: name: kube-dns-v ...

  8. vue-router总结2

    在上一篇总结了vue-router中的路由切换.重定向和路由传参等知识,因为篇幅的原因,便将剩下的路由模块化.路由嵌套.history模式.路由守卫等放在这里来写了.因为是继续前面的写.所以代码也还是 ...

  9. struts Action设置数据的方法

    一.属性驱动 注:示例中的实体类没有相应展示出来 1.基本数据类型的属性 基本数据类型的属性指每一个前台提交的属性在后台对应的Action类中都有相应的属性与之相对应 例如:前台表单: <for ...

  10. 获取Android文件路径

    Environment.getDataDirectory().getPath() : /data Environment.getDownloadCacheDirectory().getPath() : ...