当前位置:网站首页>可重入锁详解(什么是可重入)
可重入锁详解(什么是可重入)
2022-08-03 12:17:00 【全栈程序员站长】
大家好,又见面了,我是你们的朋友全栈君。
可重入锁详解
概述
什么是 “可重入”,可重入就是说某个线程已经获得某个锁,可以再次获取锁而不会出现死锁。例如
package com.test.reen;
// 演示可重入锁是什么意思,可重入,就是可以重复获取相同的锁,synchronized和ReentrantLock都是可重入的
// 可重入降低了编程复杂性
public class WhatReentrant {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public 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() {
@Override
public 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() {
@Override
public 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() {
@Override
public 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();
}
}发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/124905.html原文链接:https://javaforall.cn
边栏推荐
- [数据仓库]分层概念,ODS,DM,DWD,DWS,DIM的概念「建议收藏」
- 使用.NET简单实现一个Redis的高性能克隆版(一)
- 深入理解MySQL事务MVCC的核心概念以及底层原理
- 如何免费获得一个市全年的气象数据?降雨量气温湿度太阳辐射等等数据
- 15. PARTITIONS「建议收藏」
- 【Verilog】HDLBits题解——Circuits/Sequential Logic/Latches and Flip-Flops
- How to do App Automation Testing?Practical sharing of the whole process of App automation testing
- nacos应用
- [Verilog] HDLBits Problem Solution - Verification: Writing Testbenches
- 【云原生 · Kubernetes】部署Kubernetes集群
猜你喜欢

Explain the virtual machine in detail!JD.com produced HotSpot VM source code analysis notes (with complete source code)

肝完Alibaba这份面试通关宝典,我成功拿下今年第15个Offer

C language advanced article: memory function

net start mysql 启动报错:发生系统错误5。拒绝访问。

第3章 搭建短视频App基础架构

从零开始C语言精讲篇5:指针

899. 有序队列

nacos app

Go 语言快速入门指南: 介绍及安装

PolarFormer: Multi-camera 3D Object Detection with Polar Transformers 论文笔记
随机推荐
Apache APISIX 2.15 版本发布,为插件增加更多灵活性
bash for loop
Image fusion GAN-FM study notes
数据库系统原理与应用教程(076)—— MySQL 练习题:操作题 160-167(二十):综合练习
R语言拟合ARIMA模型并使用拟合模型进行预测推理、使用autoplot函数可视化ARIMA模型预测结果、可视化包含置信区间的预测结果
深入理解MySQL事务MVCC的核心概念以及底层原理
随机森林项目实战---气温预测
如何免费获得一个市全年的气象数据?降雨量气温湿度太阳辐射等等数据
flink流批一体有啥条件,数据源是从mysql批量分片读取,为啥设置成批量模式就不行
5个超好用手机开源自动化工具,哪个适合你?
(through page) ali time to upload the jar
Chapter 15 Source Code File REST API Introduction
基于英雄联盟的知识图谱问答系统
使用.NET简单实现一个Redis的高性能克隆版(一)
特征工程学习笔记
php microtime 封装工具类,计算接口运行时间(打断点)
[Verilog] HDLBits Problem Solution - Verification: Writing Testbenches
长江商业银行面试
【Verilog】HDLBits题解——验证:阅读模拟
word标尺有哪些作用