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

Java ReentrantLock 核心用法

ReentrantLock 是 Java 中处理并发问题的强大工具,用于解决多线程下的竞态条件(如 count++ 操作导致的数据不一致)。本文旨在展示其最核心、最标准的用法。

1. 实战代码示例

以下代码通过对比加锁与否,直观展示 ReentrantLock 的作用。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;public class ReentrantLockDemo {// 1. 实例化一个 ReentrantLockprivate final ReentrantLock lock = new ReentrantLock();private int count = 0;/*** 不使用锁的递增方法(线程不安全)*/public void incrementWithoutLock() {count++;}/*** 使用 ReentrantLock 的递增方法(线程安全)*/public void incrementWithLock() {// 2. 获取锁lock.lock();try {// 3. 在 try 块中执行所有共享资源操作count++;} finally {// 4. 在 finally 块中释放锁,确保锁一定会被释放lock.unlock();}}public int getCount() {return count;}public void reset() {count = 0;}public static void main(String[] args) throws InterruptedException {final int threadCount = 100;final int incrementsPerThread = 1000;final int expectedCount = threadCount * incrementsPerThread;ExecutorService executor = Executors.newFixedThreadPool(threadCount);ReentrantLockDemo demo = new ReentrantLockDemo();// --- 场景一:不使用锁 ---System.out.println("--- 场景一:不使用锁 (线程不安全) ---");for (int i = 0; i < threadCount; i++) {for (int j = 0; j < incrementsPerThread; j++) {executor.submit(demo::incrementWithoutLock);}}executor.shutdown();executor.awaitTermination(5, TimeUnit.SECONDS);System.out.println("预期结果: " + expectedCount);System.out.println("实际结果: " + demo.getCount());System.out.println("-------------------------------------\n");// --- 场景二:使用 ReentrantLock ---System.out.println("--- 场景二:使用 ReentrantLock (线程安全) ---");demo.reset();executor = Executors.newFixedThreadPool(threadCount);for (int i = 0; i < threadCount; i++) {for (int j = 0; j < incrementsPerThread; j++) {executor.submit(demo::incrementWithLock);}}executor.shutdown();executor.awaitTermination(5, TimeUnit.SECONDS);System.out.println("预期结果: " + expectedCount);System.out.println("实际结果: " + demo.getCount());System.out.println("-------------------------------------");}
}

2. 运行结果

--- 场景一:不使用锁 (线程不安全) ---
预期结果: 100000
实际结果: 99654
---------------------------------------- 场景二:使用 ReentrantLock (线程安全) ---
预期结果: 100000
实际结果: 100000
-------------------------------------

结果清晰地表明,不使用锁导致了数据错误,而 ReentrantLock 保证了计算的正确性。

3. 核心使用范式

ReentrantLock 的使用必须遵循以下结构,以确保锁在任何情况下(包括异常)都能被释放,从而防止死锁。

lock.lock(); // 1. 获取锁
try {// 2. 执行需要保护的代码
} finally {lock.unlock(); // 3. 在 finally 块中释放锁
}

结论:synchronized 的自动锁管理不同,ReentrantLock 需要开发者手动保证锁的释放。严格遵守 try-finally 范式是正确使用 ReentrantLock 的关键。

http://www.dtcms.com/a/341291.html

相关文章:

  • 算法提升树形数据结构-(线段树)
  • RAG拓展、变体、增强版(二)
  • Django管理后台结合剪映实现课件视频生成应用
  • SpringBoot+Vue打造动漫活动预约系统----后端
  • BM25 系列检索算法
  • Python Day32 JavaScript 数组与对象核心知识点整理
  • 用 Go 库 urfave/cli 轻松构建命令行程序
  • Linux上安装多个JDK版本,需要配置环境变量吗
  • STM32存储结构
  • Vue3 结合 html2canvas 生成图片
  • GISBox工具:FBX到3DTiles文件转换指南
  • SpringBoot - 公共字段自动填充的6种方案
  • 使用安卓平板,通过USB数据线(而不是Wi-Fi)来控制电脑(版本1)
  • Mac编译Android AOSP
  • Vue2+Vue3前端开发_Day3
  • vue3中,如何解决数字精度问题(big.js的使用)
  • 计算机毕设Spark项目实战:基于大数据技术的就业数据分析系统Django+Vue开发指南
  • SQL count(*)与 sum 区别
  • 【iOS】NSRunLoop
  • Preprocessing Model in MPC 2 - 背景、基础原语和Beaver三元组
  • 计算机网络--HTTP协议
  • Jenkins服务器配置SSH
  • 强制重启导致Ubuntu24.04LTS amd的WIFI无法使用的解决方案
  • 超长视频生成新突破!LongVie框架问世,创作不再受时长限制
  • spring第9课,spring对DAO的支持
  • C语言---编译的最小单位---令牌(Token)
  • 基于 Java 调用泛微 OA WebService 创建表单流程
  • 如何保障内部网络安全前提下,实现与外部互联网之间的文件传输?
  • 一种融合AI与OCR的施工许可证识别技术,提升工程监管效率,实现自动化、精准化处理。
  • 【CUDA编程】CUDA编程入门第一课