ReentrantLock 原理你都知道吗?

简介: 通过以上步骤和示例代码,你应该对 ReentrantLock 的工作原理有了清晰的理解。欢迎关注威哥爱编程,一起学习成长。

在Java中,ReentrantLock 是实现再入锁(Reentrant Lock)的一个类,它属于 java.util.concurrent.locks 包。下面详细介绍 ReentrantLock 的原理,逻辑步骤,以及提供示例代码。

ReentrantLock 原理

  1. 线程安全性:ReentrantLock 提供了线程安全的锁定机制。

  2. 可重入性:与 synchronized 不同,ReentrantLock 明确地暴露了其可重入性质。如果当前线程已经持有锁,那么该线程可以再次获取锁而不会被阻塞。

  3. 公平性选择:ReentrantLock 允许你选择锁的公平性。公平性指的是锁的获取顺序按照请求的顺序进行。

  4. 尝试非阻塞获取:ReentrantLock 提供了尝试获取锁的方法,如果锁不可用,调用者可以不阻塞地继续执行。

  5. 超时获取:ReentrantLock 还提供了带超时的获取锁的方法,如果超过指定时间还不能获取到锁,将返回。

ReentrantLock 逻辑步骤

  1. 创建锁:首先,你需要创建一个 ReentrantLock 对象。

  2. 获取锁:在访问共享资源之前,线程必须通过调用 lock() 方法来获取锁。

  3. 重入获取锁:如果当前线程已经持有锁,再次调用 lock() 方法时,锁的计数会增加。

  4. 释放锁:线程完成对共享资源的访问后,必须通过调用 unlock() 方法来释放锁,锁的计数会减少。

  5. 锁的公平性:如果锁是公平的,那么等待时间最长的线程将会最先获取到锁。

示例代码

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockExample {
   

    // 创建锁对象,可以选择性地传入fair参数来指定是否公平
    private Lock lock = new ReentrantLock(true); // 公平锁

    public void performAction() {
   
        // 尝试获取锁
        lock.lock();
        try {
   
            // 线程安全地执行代码
            doSomething();
        } finally {
   
            // 释放锁
            lock.unlock();
        }
    }

    private void doSomething() {
   
        // 模拟一些操作
        System.out.println("Performing some action");
        // 假设需要再次获取锁进行操作
        lock.lock();
        try {
   
            // 再次执行线程安全的操作
            System.out.println("Performing another action");
        } finally {
   
            // 释放锁
            lock.unlock();
        }
    }

    public static void main(String[] args) {
   
        ReentrantLockExample example = new ReentrantLockExample();
        example.performAction();
    }
}

注意事项

  1. 使用 ReentrantLock 时,务必在 finally 块中释放锁,以避免在发生异常时死锁。
  2. ReentrantLock 是一个重的锁,相比 synchronized,它在竞争激烈的情况下性能更好,但在低并发下,synchronized 的开销可能更小。
  3. 根据需要选择锁的公平性。非公平锁通常响应更快,但可能导致饥饿现象。

通过以上步骤和示例代码,你应该对 ReentrantLock 的工作原理有了清晰的理解。欢迎关注威哥爱编程,一起学习成长。

相关文章
|
存储 安全 Java
ConcurrentHashMap底层实现原理
ConcurrentHashMap底层实现原理
1089 0
|
监控 Java 应用服务中间件
谈谈你对spring boot 3.0的理解
1. Java 版本要求:Spring Boot 3.0 要求使用 Java 17 或更高版本,这可能会对一些仍在使用旧版 Java 的项目造成兼容性问题。需要确保项目使用的 Java 版本符合要求,并考虑是否需要升级 JDK 版本。 2. 底层依赖项迁移:Spring Boot 3.0 将所有底层依赖项从 Java EE 迁移到了 Jakarta EE API,基于 Jakarta EE 9 并尽可能地兼容 Jakarta EE 10。这可能会对一些使用了 Java EE 的应用造成影响,需要进行相应的修改和调整。 3. 插件和库的支持:尽管 Spring Boot 3.0 支持更多的插件和
2300 0
|
SQL 关系型数据库 数据库
学习分布式事务Seata看这一篇就够了,建议收藏
学习分布式事务Seata看这一篇就够了,建议收藏
26386 2
|
7月前
|
安全 Java
深入拆解 ReentrantLock:从底层实现到生产最佳实践
本文深入剖析ReentrantLock底层原理,基于AQS框架详解state状态、CLH队列及公平/非公平锁机制;对比synchronized在实现、功能(可中断、多条件变量)和性能上的差异;结合代码演示三类锁适用场景与最佳实践,助你写出高效、健壮的并发程序。
544 4
|
人工智能 缓存 监控
使用LangChain4j构建Java AI智能体:让大模型学会使用工具
AI智能体是大模型技术的重要演进方向,它使模型能够主动使用工具、与环境交互,以完成复杂任务。本文详细介绍如何在Java应用中,借助LangChain4j框架构建一个具备工具使用能力的AI智能体。我们将创建一个能够进行数学计算和实时信息查询的智能体,涵盖工具定义、智能体组装、记忆管理以及Spring Boot集成等关键步骤,并展示如何通过简单的对话界面与智能体交互。
3809 1
|
SQL 人工智能 Java
30分钟轻松掌握Cursor,快速提升开发效率和体验
本文通过在WebX老项目中实践,验证了Cursor利用AI大模型可高效生成符合老旧项目规范的代码框架,显著提升开发效率与体验。
30分钟轻松掌握Cursor,快速提升开发效率和体验
|
10月前
|
负载均衡 Dubbo Java
Dubbo 和 Feign的区别是什么?
Dubbo是高性能RPC框架,支持多种协议与服务治理,适用于Java微服务架构;Feign是声明式HTTP客户端,简化Spring Cloud服务调用。两者定位不同,Dubbo强在性能与治理,Feign重在易用与集成。
958 0
|
存储 SQL 关系型数据库
MySQL高级篇——索引失效的11种情况
索引优化思路、要尽量满足全值匹配、最佳左前缀法则、主键插入顺序尽量自增、计算、函数导致索引失效、类型转换(手动或自动)导致索引失效、范围条件右边的列索引失效、不等于符号导致索引失效、is not null、not like无法使用索引、左模糊查询导致索引失效、“OR”前后存在非索引列,导致索引失效、不同字符集导致索引失败,建议utf8mb4
MySQL高级篇——索引失效的11种情况
|
SpringCloudAlibaba Java 网络架构
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(七)Spring Cloud Gateway服务网关
【Springcloud Alibaba微服务分布式架构 | Spring Cloud】之学习笔记(七)Spring Cloud Gateway服务网关
2272 0