当前位置: 首页 > news >正文

JUC笔记之ReentrantLock

ReentrantLock

相对于synchronized它具备如下特点

· 可中断

· 可以设置超时时间

· 可以设置为公平锁

· 支持多个条件变量(多个wait set,不同于synchronized的wait set,ReentrantLock的wait set在同一条件下notify才能唤醒WATING状态的线程)

与synchronized一样,都支持可重入

基本语法

//获取锁
ReentrantLock reentrantLock = new ReentrantLock();
reentrantLock.lock();
try{//临界区
}finally{//释放锁reentrantLock.unlock();
}

可重入

可重入是指同一个线程如果首次获得了这把锁,那么因为它是这把锁的持有者,因此有权力再次获取这把锁。如果是不可重入锁,那么第二次获得锁时,自己也会被锁挡住

代码体现

@Slf4j(topic = "c.Demo")
public class Demo {private static ReentrantLock reentrantLock = new ReentrantLock();public static void main(String[] args) {reentrantLock.lock();try {log.debug("enter main");m1();}finally {reentrantLock.unlock();}}public static void m1(){reentrantLock.lock();try {log.debug("enter m1");m2();}finally {reentrantLock.unlock();}}public static void m2(){reentrantLock.lock();try {log.debug("enter m2");}finally {reentrantLock.unlock();}}
}

可打断

用lockInterruptibly()来生成的锁才能打断

代码体现

@Slf4j(topic = "c.Demo2")
public class Demo2 {private static ReentrantLock lock = new ReentrantLock();public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {try {//如果没有竞争那么此方法就会获取lock对象锁//如果有竞争就进入阻塞队列,可以被其他线程用 interruput 方法打断log.debug("尝试获得锁");lock.lockInterruptibly();} catch (InterruptedException e) {e.printStackTrace();log.debug("没有获得到锁");return;}try {log.debug("获取到锁");}finally {lock.unlock();}}, "t1");lock.lock();t1.start();Thread.sleep(1000);log.debug("打断 t1");t1.interrupt();}
}

锁超时

立刻失败

@Slf4j(topic = "c.Demo3")
public class Demo3 {private static ReentrantLock lock = new ReentrantLock();public static void main(String[] args) {Thread t1 = new Thread(()->{log.debug("尝试获得锁");if (!lock.tryLock()) {log.debug("获取不到锁");return;}try {log.debug("获取到锁");}finally {lock.unlock();}},"t1");lock.lock();log.debug("获取到锁");t1.start();}}

含超时时间的

@Slf4j(topic = "c.Demo3")
public class Demo3 {private static ReentrantLock lock = new ReentrantLock();public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(()->{log.debug("尝试获得锁");try {if (!lock.tryLock(2, TimeUnit.SECONDS)) {log.debug("获取不到锁");return;}} catch (InterruptedException e) {e.printStackTrace();log.debug("获取不到锁");return;}try {log.debug("获取到锁");}finally {lock.unlock();}},"t1");lock.lock();log.debug("获取到锁");t1.start();Thread.sleep(1000);log.debug("释放了锁");lock.unlock();}}

用ReentrantLock解决哲学家用餐问题

筷子类

class Chopstick extends ReentrantLock {String name;public Chopstick(String name) {this.name = name;}@Overridepublic String toString() {return "Chopstick{" +"name='" + name + '\'' +'}';}
}

哲学家类

@Slf4j(topic = "c.Philosopher")
class Philosopher extends Thread{Chopstick left;Chopstick right;public Philosopher(String name, Chopstick left, Chopstick right){super(name);this.left = left;this.right = right;}@Overridepublic void run() {while (true){//尝试获得左手筷子if (left.tryLock()) {try {//尝试获取右手筷子if (right.tryLock()) {try {eat();}finally {right.unlock();}}}finally {left.unlock();//释放手里的左筷子}}}}private void eat(){log.debug("eating...");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}
}

test类

@Slf4j(topic = "c.SoleDeadLockDemo")
public class SoleDeadLockDemo {public static void main(String[] args) {Chopstick c1 = new Chopstick("1");Chopstick c2 = new Chopstick("2");Chopstick c3 = new Chopstick("3");Chopstick c4 = new Chopstick("4");Chopstick c5 = new Chopstick("5");new Philosopher("哲学1",c1,c2).start();new Philosopher("哲学2",c2,c3).start();new Philosopher("哲学3",c3,c4).start();new Philosopher("哲学4",c4,c5).start();new Philosopher("哲学5",c5,c1).start();}
}

公平锁

ReentrantLock默认是不公平的,但是可以通过构造方法改成公平的

ReentrantLock reentrantLock = new ReentrantLock(true);

公平锁一般没有必要,会降低并发度。

条件变量

synchronized中也有条件变量,就是waitSet休息室,当条件不满足时进入waitSet等待

ReentrantLock的条件变量比synchronized强大之处在于,它是支持多个条件变量的,这就好比

· synchronized是那些不满足条件的线程都在一间休息室等消息

· 而ReentrantLock支持多间休息室,唤醒时也是按休息室来唤醒

使用流程

· await前需要获取锁

· await执行后,会释放锁,进入conditionObject等待

· await的线程被唤醒(或打断、或超时)取重新竞争lock锁

· 竞争lock锁成功后,从await后继续执行

@Slf4j(topic = "c.Demo5")
public class Demo5 {static final ReentrantLock lock = new ReentrantLock();static private boolean hasSmoke = false;static private boolean hasEat = false;static Condition smoke = lock.newCondition();static Condition eat = lock.newCondition();public static void main(String[] args) throws InterruptedException {new Thread(()->{lock.lock();try {log.debug("有烟没");while (!hasSmoke) {log.debug("没烟我先休息");try {smoke.await();} catch (InterruptedException e) {e.printStackTrace();}}log.debug("有烟,那没事了");}finally {lock.unlock();}},"小男").start();new Thread(()->{lock.lock();try {log.debug("有饭没");while (!hasEat){log.debug("没饭我先休息了");try {eat.await();} catch (InterruptedException e) {e.printStackTrace();}}log.debug("有饭那没事了");}finally {lock.unlock();}},"小女").start();Thread.sleep(1000);new Thread(()->{lock.lock();try {log.debug("送饭的到了");hasEat = true;eat.signal();}finally {lock.unlock();}},"送饭的").start();Thread.sleep(1000);new Thread(()->{lock.lock();try {log.debug("送烟的到了");hasSmoke = true;smoke.signal();}finally {lock.unlock();}},"送烟的").start();}
}

相关文章:

JUC笔记之ReentrantLock

ReentrantLock 相对于synchronized它具备如下特点 可中断 可以设置超时时间 可以设置为公平锁 支持多个条件变量(多个wait set,不同于synchronized的wait set,ReentrantLock的wait set在同一条件下notify才能唤醒WATING状态的线程) 与synchronized一样,都支持可重入 …...

【含文档】基于ssm+jsp的图书管理系统(含源码+数据库+lw)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: apache tomcat 主要技术: Java,Spring,SpringMvc,mybatis,mysql,vue 2.视频演示地址 3.功能 系统定义了两个…...

pytorch知识蒸馏测试

import torch from torch import nn,optim import torch.utils import torch.utils.data import torch.utils.data.dataloader from torchvision import transforms,datasets...

mutable用法

mutable 关键字用于允许类的某个成员变量在 const 成员函数中被修改。通常,const 成员函数不能改变对象的任何成员变量,但将成员变量声明为 mutable 可以例外 class Hero { public:Hero():m_Hp(0), m_getHpCounter(0){}int getHp() const {m_getHpCounte…...

SQL语言基础

SQL(Struct Query Language)是结构化查询语言的简称,是一种在关系型数据库中定义和操纵数据的标准语言。 不要使用面向对象的思想学习SQL,因为它不是面向对象的语言目标 SQL语言简介(了解)从数据库数据检索数据(重点)子查询(重点)Oracle常用函数(掌握) …...

在USB电源测试中如何降低测试成本?-纳米软件

USB 电源模块在现代电子设备中广泛应用,其性能的稳定性和可靠性至关重要。然而,测试 USB 电源模块的成本可能会很高,这对于企业和研发机构来说是一个重要的问题。因此,寻找降低 USB 电源模块测试成本的方法具有重要的现实意义。 降…...

springboot - 定时任务

定时任务是企业级应用中的常见操作 定时任务是企业级开发中必不可少的组成部分,诸如长周期业务数据的计算,例如年度报表,诸如系统脏数据的处理,再比如系统性能监控报告,还有抢购类活动的商品上架,这些都离不…...

一篇文章理解CSS垂直布局方法

方法1&#xff1a;align-content: center 在 2024 年的 CSS 原生属性中允许使用 1 个 CSS 属性 align-content: center进行垂直居中。 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewpo…...

SpringBoot day 1105

ok了家人们&#xff0c;今天继续学习spring boot&#xff0c;let‘s go 六.SpringBoot实现SSM整合 6.1 创建工程&#xff0c;导入静态资源 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</…...

MySQL 完整教程:从入门到精通

MySQL 完整教程&#xff1a;从入门到精通 MySQL 是一个广泛使用的关系型数据库管理系统&#xff0c;它使用结构化查询语言 (SQL) 来管理和操作数据。本文将详细介绍 MySQL 的基本概念、安装与配置、常用 SQL 语法、数据表的创建与管理、索引、视图、存储过程、触发器等高级特性…...

【贝叶斯公式】贝叶斯公式、贝叶斯定理、贝叶斯因子,似然比

一、是什么&#xff1f; 贝叶斯公式的本质在于它提供了一种在已有知识的基础上更新和调整我们对事件的信念的方式。具体来说&#xff0c;贝叶斯公式描述了后验概率&#xff08;即在观察到某些证据后更新的概率&#xff09;与先验概率&#xff08;即在没有观察证据之前的概率&a…...

[libos源码学习 1] Liboc协程生产者消费者举例

文章目录 1. CoRoutineEnv_t结构体用于管理协程环境 3 Liboc协程生产者消费者例子4 Liboc协程生产者消费者&#xff0c; 为什么队列不需要上锁&#xff1f;5. 两个协程访问资源不需要加队列吗5. 参考 1. CoRoutineEnv_t结构体用于管理协程环境 struct stCoRoutineEnv_t { stCo…...

Python OpenCV 图像改变

更改图像数据 通过 改像素点 或者 切片的区域 import cv2 import numpy as np img cv2.imread("image.jpg") print(img[3,5]) # 显示某位置(行3列5)的像素值( 如 [53 34 29] 它是有三通道 B G R 组成) img[3,5] (0,0,255) # 更改该位置的像素…...

k8s按需创建 PV和创建与使用 PVC

在 Kubernetes 中&#xff0c;PersistentVolume&#xff08;PV&#xff09;和 PersistentVolumeClaim&#xff08;PVC&#xff09;用于管理存储资源。PV 是集群中的存储资源&#xff0c;而 PVC 是 Pod 请求 PV 的方式。按需创建 PV 通常使用 StorageClass 实现动态存储分配&…...

揭秘云计算 | 2、业务需求推动IT发展

揭秘云计算 | 1、云从哪里来&#xff1f;-CSDN博客https://blog.csdn.net/Ultipa/article/details/143430941?spm1001.2014.3001.5502 书接上文&#xff1a; 过去几十年间IT行业从大型主机过渡到客户端/服务器&#xff0c;再过渡到现如今的万物互联&#xff0c;IT可把控的资…...

【系统面试篇】进程与线程类(2)(笔记)——进程调度、中断、异常、用户态、核心态

目录 一、相关面试题 1. 进程的调度算法有哪些&#xff1f; 调度原则 &#xff08;1&#xff09;先来先服务调度算法 &#xff08;2&#xff09;最短作业优先调度算法 &#xff08;3&#xff09;高响应比优先调度算法 &#xff08;4&#xff09;时间片轮转调度算法 &am…...

基于MySQL的企业专利数据高效查询与统计实现

背景 在进行产业链/产业评估工作时&#xff0c;我们需要对企业的专利进行评估&#xff0c;其中一个重要指标是统计企业每一年的专利数量。本文基于MySQL数据库&#xff0c;通过公司名称查询该公司每年的专利数&#xff0c;实现了高效的专利数据统计。 流程 项目流程概述如下&…...

热成像手机VS传统热成像仪:AORO A23为何更胜一筹?

热成像技术作为一种非接触式测温方法&#xff0c;广泛应用于石油化工巡检、电力巡检、应急救援、医疗、安防等“危、急、特”场景。提及热成像设备&#xff0c;人们往往会首先想到价格高昂、操作复杂且便携性有限的热成像仪。但是&#xff0c;随着技术的不断进步&#xff0c;市…...

Spring IoC——依赖注入

1. 依赖注入的介绍 DI&#xff0c;也就是依赖注入&#xff0c;在容器中建立的 bean &#xff08;对象&#xff09;与 bean 之间是有依赖关系的&#xff0c;如果直接把对象存在 IoC 容器中&#xff0c;那么就都是一个独立的对象&#xff0c;通过建立他们的依赖关系&#xff0c;…...

Linux 中,flock 对文件加锁

在Linux中&#xff0c;flock是一个用于对文件加锁的实用程序&#xff0c;它可以帮助协调多个进程对同一个文件的访问&#xff0c;避免出现数据不一致或冲突等问题。以下是对flock的详细介绍&#xff1a; 基本原理 flock通过在文件上设置锁来控制多个进程对该文件的并发访问。…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践

6月5日&#xff0c;2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席&#xff0c;并作《智能体在安全领域的应用实践》主题演讲&#xff0c;分享了在智能体在安全领域的突破性实践。他指出&#xff0c;百度通过将安全能力…...

Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理

引言 Bitmap&#xff08;位图&#xff09;是Android应用内存占用的“头号杀手”。一张1080P&#xff08;1920x1080&#xff09;的图片以ARGB_8888格式加载时&#xff0c;内存占用高达8MB&#xff08;192010804字节&#xff09;。据统计&#xff0c;超过60%的应用OOM崩溃与Bitm…...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面&#xff0c;避免重复抓取&#xff0c;以节省资源和时间。 在分布式环境下&#xff0c;增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路&#xff1a;将增量判…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...