深入理解ReentrantLock

news2024/11/29 11:40:25

深入理解ReentrantLock

在Java并发编程中,锁(Lock)是控制多个线程对共享资源访问的重要工具。虽然Synchronized关键字是实现锁的常用方式,但它在功能上比较有限。ReentrantLockjava.util.concurrent.locks包中提供的一个更加灵活和强大的锁实现,它是一个可重入的互斥锁,它允许线程在获取锁之后再次获取该锁而不被阻塞。简单来说,如果一个线程已经持有了一个锁,再次请求获取该锁时,它可以成功获取而不会被阻塞。

ReentrantLock的基本用法

使用ReentrantLock的基本步骤包括创建锁实例、加锁和解锁。以下是一个简单的例子:

import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockExample {
    private final ReentrantLock lock = new ReentrantLock();

    public void performTask() {
        lock.lock();
        try {
            // 关键代码段
            System.out.println("Lock is held by: " + Thread.currentThread().getName());
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        ReentrantLockExample example = new ReentrantLockExample();
        Runnable task = () -> example.performTask();
        
        Thread t1 = new Thread(task, "Thread-1");
        Thread t2 = new Thread(task, "Thread-2");
        
        t1.start();
        t2.start();
    }
}

在这个例子中,我们创建了一个ReentrantLock实例,并在performTask方法中使用lock.lock()来获取锁,lock.unlock()来释放锁。在try块中执行关键代码以确保在任何情况下都会释放锁。

ReentrantLock的高级功能

可重入性

正如前面提到的,ReentrantLock是可重入的。这意味着同一个线程可以多次获取同一个锁而不会陷入死锁。以下示例展示了这一特性:

public void reentrantLockExample() {
    lock.lock();
    try {
        System.out.println("First lock acquired.");
        lock.lock();
        try {
            System.out.println("Second lock acquired.");
        } finally {
            lock.unlock();
        }
    } finally {
        lock.unlock();
    }
}

公平锁与非公平锁

ReentrantLock可以被配置为公平锁或非公平锁。公平锁意味着线程将以请求锁的顺序(FIFO)获得锁,而非公平锁则可能让某些线程“插队”。默认情况下,ReentrantLock是非公平的。要创建公平锁,可以使用以下代码:

ReentrantLock fairLock = new ReentrantLock(true);

可中断锁获取

ReentrantLock提供了一种机制,可以让线程在尝试获取锁时被中断。使用lock.lockInterruptibly()方法,可以在获取锁的过程中响应中断:

public void performInterruptibleTask() {
    try {
        lock.lockInterruptibly();
        try {
            // 关键代码段
        } finally {
            lock.unlock();
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        // 处理中断
    }
}

超时锁获取

ReentrantLock还允许在获取锁时指定超时时间。如果在指定时间内无法获取锁,线程将会放弃获取锁的尝试:

public void performTimedTask() {
    try {
        if (lock.tryLock(5, TimeUnit.SECONDS)) {
            try {
                // 关键代码段
            } finally {
                lock.unlock();
            }
        } else {
            System.out.println("Could not acquire lock within 5 seconds");
        }
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        // 处理中断
    }
}

ReentrantLock与Synchronized的对比

灵活性

ReentrantLockSynchronized更加灵活,提供了可中断的锁获取、超时锁获取和公平锁等特性。而Synchronized则相对简单,只能用于基本的互斥锁定。

性能

在高竞争环境下,ReentrantLock可能表现得比Synchronized更好,因为它内部使用了一些优化策略,比如自旋锁。

可见性

ReentrantLock提供了isHeldByCurrentThread()等方法,可以方便地检测锁的状态,而Synchronized则没有这种直接的方法。

参考链接

  • Java 官方并发教程
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1824994.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python基础教程(十九):网络编程

💝💝💝首先,欢迎各位来到我的博客,很高兴能够在这里和您见面!希望您在这里不仅可以有所收获,同时也能感受到一份轻松欢乐的氛围,祝你生活愉快! 💝&#x1f49…

【吊打面试官系列-Mysql面试题】实践中如何优化 MySQL?

大家好,我是锋哥。今天分享关于 【实践中如何优化 MySQL?】面试题,希望对大家有帮助; 实践中如何优化 MySQL? 最好是按照以下顺序优化: 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 1、SQL 语…

组件化框架 ARouter 完全解析(一)

一、路由认知 ARouter从命名即可知,这是一个路由框架。那么路由是个啥呢? 路由(routing)就是通过互联的网络把信息从源地址传输到目的地址的活动。-- 百科 可见 路由 是个动词,这是网络传输中的概念,完成路…

跨境电商测评、采购大额下单自养号需要解决哪些技术原理?

市场上有许多伪装工具,但大多数只是为了方便开发人员测试系统程序,它们并不能针对特定的电商平台进行伪装。每个电商平台都有其独特的风控机制,因此,我们需要从硬件环境的底层配合软件控制,以满足各平台的检测规则。 …

Spring boot 使用AbstractRoutingDataSource实现数据源动态切换

目录 一、AbstractRoutingDataSource 二、具体实现 1、pom.xml 2、新建UserMapper 3、在spring boot 启动类上添加扫描mapper注解 4、在配置文件 application.properties 中添加多个(我这里是两个)数据源的配置信息 5、集成动态数据源模块 5.1、新建注解 CurDataSource…

【复旦邱锡鹏教授《神经网络与深度学习公开课》笔记】梯度的反向传播算法

矩阵微积分(Matrix Calculus) 在开始之前,需要先了解矩阵微积分的一些计算规则。 首先,对于矩阵微积分的表示,通常由两种符号约定: 分母布局 标量关于向量的导数为列向量 向量关于标量的导数为行向量 N维…

C# Winform Datagridview查询项目实例

在项目中,我们经常要遇到查询和展示内容,常用的做法是通过文本框,时间控件,按键和datagridview查询和展示内容。下面是一个常见的综合实例,并支持Excel(csv)导入导出,表格列动态调整的功能。 实例代码链接&…

【python-AI篇】人工智能技能树思维导图

大致总结一下得出如下思维导图,如不完善日后迭代更新 1. python基础三方库 1.1 科学计算库 ---- numpy库 1.2 科学计算库 ---- Scipy库 1.3 数据分析处理库 ---- pandas库 1.4 可视化库 ---- matplotlib库 1.5 可视化库 ---- seaborn库 1.6 机器学习和数据挖掘库 …

springboot网上书店管理系统-计算机毕业设计源码03780

摘 要 网上书店管理系统采用B/S结构、java开发语言、以及Mysql数据库等技术。系统主要分为管理员和用户两部分,管理员管理主要功能包括:首页、站点管理(轮播图)用户管理(管理员、注册用户)内容管理&#x…

OpenCV 4.10 发布

OpenCV 4.10 JPEG 解码速度提升 77%,实验性支持 Wayland、Win ARM64 根据 “OpenCV 中国团队” 介绍,从 4.10 开始 OpenCV 对 JPEG 图像的读取和解码有了 77% 的速度提升,超过了 scikit-image、imageio、pillow。 4.10 版本的一些亮点&…

第N4周:中文文本分类-Pytorch实现

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 | 接辅导、项目定制🚀 文章来源:K同学的学习圈子 目录 一、准备工作 1.任务说明 文本分类流程图: 2.加载数据 ​编辑 二、…

第2章 Rust初体验7/8:错误处理时不关心具体错误类型的下划线:提高代码可读性:猜骰子冷热游戏

讲动人的故事,写懂人的代码 2.6.6 用as进行类型转换:显式而简洁的语法 贾克强:“大家在查看Rust代码时,可能会注意到这一句。在这里,如果我们不使用as i32,编译器会报错,因为它在u32中找不到abs()方法。这是因为prev和sum_of_two_dice都是u32类型,u32类型并不支持abs(…

【LLM】吴恩达『微调大模型』课程完全笔记

Finetuning Large Language Models 版权说明: 『Finetuning Large Language Models』是DeepLearning.AI出品的免费课程,版权属于DeepLearning.AI(https://www.deeplearning.ai/)。 本文是对该课程内容的翻译整理,只作为教育用途,不…

4-字符串-11-反转字符串-LeetCode344

4-字符串-11-反转字符串-LeetCode344 LeetCode: 题目序号344 更多内容欢迎关注我(持续更新中,欢迎Star✨) Github:CodeZeng1998/Java-Developer-Work-Note 技术公众号:CodeZeng1998(纯纯技术文&#xff0…

【牛客面试必刷TOP101】Day32.BM68 矩阵的最小路径和和BM69 把数字翻译成字符串

文章目录 前言一、BM68 矩阵的最小路径和题目描述题目解析二、BM69 把数字翻译成字符串题目描述题目解析总结 前言 一、BM68 矩阵的最小路径和 题目描述 描述: 给定两个字符串str1和str2,输出两个字符串的最长公共子序列。如果最长公共子序列为空&#x…

Ubuntu系统环境配置

Ubuntu安装terminator以及美化 安装 sudo apt-get install terminator美化 修改或者创建.config/terminator/config文件,添加如下配置 [global_config]suppress_multiple_term_dialog Truetitle_font Sans 11title_use_system_font False [keybindings] [lay…

supOS助力中核陕西铀浓缩有限公司迈向智能化、数字化、绿色化

中核陕西铀浓缩有限公司是中国核工业集团有限公司所属大型生产骨干企业,建于1969年10月,是我国第一座采用离心法生产浓缩铀的工厂。 蓝卓基于supOS工业操作系统,以“三化一平台一基础”的顶层架构,面向陕铀公司工艺优化、设备管理…

【Photoshop】PS修改文字内容

Photoshop(PS)修改图片上文字内容,网上教材不少,本人整理实践过的方法,分享给各位。本人实践方法: 内容识别填充:适用于背景色复杂的图片内容修补工具:适用于背景色为纯色的图片 方式一:内容识…

el-table表头文字换行或者修改字体颜色样式

例如 <el-table:data"tableData":header-cell-style"headClass" style"width: 100%;" border ><el-table-columnprop"address"label"生产工序"align"center"></el-table-column> //重点看这里…

uniapp 开发版小程序之间跳转

uni.navigateToMiniProgram({appId: urL,path: patH,envVersion: release,//我使用develop会给我返回&#xff1a;开发版小程序已过期&#xff0c;请在开发者工具重新扫码确定success(res) {console.log(res);// 打开成功uni.showToast({title: 跳转成功})},fail(err) {console…