可重入锁 ReentrantLock
概述
什么是 “可重入”,可重入就是说某个线程已经获得某个锁,可以再次获取锁而不会出现死锁。
可重入锁的意义之一在于防止死锁。
package com.test.reen;// 演示可重入锁是什么意思,可重入,就是可以重复获取相同的锁,synchronized和ReentrantLock都是可重入的
// 可重入降低了编程复杂性
public class WhatReentrant {public static void main(String[] args) {new Thread(new Runnable() {@Overridepublic void run() {synchronized (this) {System.out.println("第1次获取锁,这个锁是:" + this);int index = 1;while (true) {synchronized (this) {System.out.println("第" + (++index) + "次获取锁,这个锁是:" + this);}if (index == 10) {break;}}}}}).start();}
}
package com.test.reen;import java.util.Random;
import java.util.concurrent.locks.ReentrantLock;// 演示可重入锁是什么意思
public class WhatReentrant2 {public static void main(String[] args) {ReentrantLock lock = new ReentrantLock();new Thread(new Runnable() {@Overridepublic void run() {try {lock.lock();System.out.println("第1次获取锁,这个锁是:" + lock);int index = 1;while (true) {try {lock.lock();System.out.println("第" + (++index) + "次获取锁,这个锁是:" + lock);try {Thread.sleep(new Random().nextInt(200));} catch (InterruptedException e) {e.printStackTrace();}if (index == 10) {break;}} finally {lock.unlock();}}} finally {lock.unlock();}}}).start();}
}
可以发现没发生死锁,可以多次获取相同的锁
可重入锁有
- synchronized
- ReentrantLock
使用ReentrantLock的注意点
ReentrantLock 和 synchronized 不一样,需要手动释放锁,所以使用 ReentrantLock的时候一定要手动释放锁,并且加锁次数和释放次数要一样
以下代码演示,加锁和释放次数不一样导致的死锁
package com.test.reen;import java.util.Random;
import java.util.concurrent.locks.ReentrantLock;public class WhatReentrant3 {public static void main(String[] args) {ReentrantLock lock = new ReentrantLock();new Thread(new Runnable() {@Overridepublic void run() {try {lock.lock();System.out.println("第1次获取锁,这个锁是:" + lock);int index = 1;while (true) {try {lock.lock();System.out.println("第" + (++index) + "次获取锁,这个锁是:" + lock);try {Thread.sleep(new Random().nextInt(200));} catch (InterruptedException e) {e.printStackTrace();}if (index == 10) {break;}} finally {
// lock.unlock();// 这里故意注释,实现加锁次数和释放次数不一样}}} finally {lock.unlock();}}}).start();new Thread(new Runnable() {@Overridepublic void run() {try {lock.lock();for (int i = 0; i < 20; i++) {System.out.println("threadName:" + Thread.currentThread().getName());try {Thread.sleep(new Random().nextInt(200));} catch (InterruptedException e) {e.printStackTrace();}}} finally {lock.unlock();}}}).start();}
}
由于加锁次数和释放次数不一样,第二个线程始终无法获取到锁,导致一直在等待。
稍微改一下,在外层的finally里头释放9次,让加锁和释放次数一样,就没问题了
try {lock.lock();System.out.println("第1次获取锁,这个锁是:" + lock);int index = 1;while (true) {try {lock.lock();System.out.println("第" + (++index) + "次获取锁,这个锁是:" + lock);... 代码省略节省篇幅...} finally {
// lock.unlock();// 这里故意注释,实现加锁次数和释放次数不一样}}} finally {lock.unlock();// 在外层的finally里头释放9次,让加锁和释放次数一样,就没问题了for (int i = 0; i < 9; i++) {lock.unlock();}
}
可重入锁实现原理
每一个锁关联一个owner 线程持有者 和 state 计数器,当计数器为 0 时表示该锁没有被任何线程持有,那么任何线程都可能获得该锁而调用相应的方法;当某一线程请求成功后,JVM 会记下锁的持有线程,并且将计数器置为 1;此时其它线程请求该锁,则必须等待;而该持有锁的线程如果再次请求这个锁,就可以再次拿到这个锁,同时计数器会递增;当线程退出同步代码块时,计数器会递减,如果计数器为 0,则释放该锁。(源码层面分析)
附:原理分析
本文仅介绍如何使用,如需了解 ReentrantLock 原理(源码分析),请跳转了解:可重入锁 ReentrantLock 原理分析
End
可重入锁 ReentrantLock相关推荐
- 并发编程-19AQS同步组件之重入锁ReentrantLock、 读写锁ReentrantReadWriteLock、Condition
文章目录 J.U.C脑图 ReentrantLock概述 ReentrantLock 常用方法 synchronized 和 ReentrantLock的比较 ReentrantLock示例 读写锁R ...
- Java 重入锁 ReentrantLock 原理分析
1.简介 可重入锁ReentrantLock自 JDK 1.5 被引入,功能上与synchronized关键字类似.所谓的可重入是指,线程可对同一把锁进行重复加锁,而不会被阻塞住,这样可避免死锁的产生 ...
- java中的账户冻结原理_java可重入锁(ReentrantLock)的实现原理
前言 相信学过java的人都知道 synchronized 这个关键词,也知道它用于控制多线程对并发资源的安全访问,兴许,你还用过Lock相关的功能,但你可能从来没有想过java中的锁底层的机制是怎么 ...
- java多线程---重入锁ReentrantLock
1.定义 重入锁ReentrantLock,支持重入的锁,表示一个线程对资源的重复加锁. 2.底层实现 每个锁关联一个线程持有者和计数器,当计数器为0时表示该锁没有被任何线程持有,那么任何线程都可能获 ...
- 重入锁ReentrantLock详解
重入锁ReentrantLock,顾名思义,就是支持重进入的锁,它表示该锁能够支持一个线程对资源的重复加锁.除此之外,该锁的还支持获取锁时的公平和非公平性选择. 在AQS实现中,当一个线程调用Mute ...
- Java多线程系列——深入重入锁ReentrantLock
简述 ReentrantLock 是一个可重入的互斥(/独占)锁,又称为"独占锁". ReentrantLock通过自定义队列同步器(AQS-AbstractQueuedSychr ...
- java lock可重入_Java源码解析之可重入锁ReentrantLock
本文基于jdk1.8进行分析. ReentrantLock是一个可重入锁,在ConcurrentHashMap中使用了ReentrantLock. 首先看一下源码中对ReentrantLock的介绍. ...
- Java多线程——重入锁ReentrantLock源码阅读
上一章<AQS源码阅读>讲了AQS框架,这次讲讲它的应用类(注意不是子类实现,待会细讲). ReentrantLock,顾名思义重入锁,但什么是重入,这个锁到底是怎样的,我们来看看类的注解 ...
- Java 并发编程之可重入锁 ReentrantLock
Java 提供了另外一个可重入锁,ReentrantLock,位于 java.util.concurrent.locks 包下,可以替代 synchronized,并且提供了比 synchronize ...
- JDK1.8源码分析:可重入锁ReentrantLock和Condition的实现原理
synchronized的用法和实现原理 synchronized实现线程同步的用法和实现原理 不足 synchronized在线程同步的使用方面,优点是使用简单,可以自动加锁和解锁,但是也存在一些不 ...
最新文章
- 详解 Vue Vuex 实践
- JPOM - AOP+自定义注解实现操作日志记录
- 3分钟了解dubbo服务调试管理实用命令
- Cannot find module -----Node.js编程的第一个问题
- “Survey of machine learning techniques for malware analysis ”
- SQL2000: MMC 不能打开文件
- html:(3):认识html标签和标签的语法
- 最全android Demo
- 鱼骨图分析法实际案例_会用“鱼骨图”的项目经理无难题
- zookeeper安装和使用
- 2019.08.29定时器以及轮播图
- 微服务的通信协议:Restful,RPC(Dubbo、Motan、gRPC)
- 【动态规划】leetcode 53:最大子数组和
- NLP学习—20.WMD paper及代码
- iOS 程序上传流程
- 参考文献中英文人名_英文人名的缩写和参考文献写法
- VS Visual Studio 2022调试控制台 输出不全 不完整 缺内容 少了很多代码 有屋设计拆单管理一体化软件 全屋定制拆单 橱柜衣柜整装 木门归方程序
- 小程序:npm下载使用weiui
- 传统企业互联网转型升级新玩法:技术合伙
- Spring AOP 标签形式及Around增强处理
热门文章
- Excel催化剂开源第6波-Clickonce部署之自动升级瘦身之术
- bert tensorflow2 serving部署
- java thrift使用指南_Thrift使用指南
- 魔众刮刮卡抽奖系统 v2.0.0 支付抽奖,更好用的刮刮卡系统
- 硬盘分区大学计算机,电脑硬盘容量要怎么选?又要怎么硬盘合理分区?今天我再说一次!...
- HomeKit 设备接入协议
- 《程序员的自我修养》学习笔记之温故而知新
- 记一次云主机如何挂载对象存储
- 四个Channel的讲解
- php执行fastlane,fastlane教程