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

ReentrantLock存在的意义到底是什么

在使用ReentrantLock之前我们已经知道了synchronized,所以我自己也对它的使用不是那么清楚

先来个效果图

image

 这是什么都不使用的情况,顺序是乱的,使用后

image

 它是属于有序打印的

来看点更细致的

image

 看到没,这就是区别。synchronized是独占,但是ReentrantLock没拿到就不会干等,它会去干些能干的事,这就是很本质的区别

同时

private static final ReentrantLock lock = new ReentrantLock(true);

  和

 private static ReentrantLock lock = new ReentrantLock(false);

  可以让程序插队或者不让插队

代码部分

package com.java.test.lock;import lombok.extern.slf4j.Slf4j;import java.util.concurrent.locks.ReentrantLock;/*** @Description:* @Author: tutu-qiuxie* @Create: 2026/4/30 23:46*/
@Slf4j
public class LockTest001 {private static int count = 0;private static final ReentrantLock lock = new ReentrantLock(true);public static void main(String[] args) {for (int i = 0; i < 5; i++) {new Thread(() -> {boolean success = lock.tryLock();if (!success) {log.info(Thread.currentThread().getName() + " 没抢到锁,直接走了");return;}try {int temp = count;temp++;count = temp;log.info(Thread.currentThread().getName() + " -> " + count);} finally {lock.unlock();}}, String.valueOf(i)).start();}}}

  来看点不一样的

image

 非公平锁,插队程序实现功能

但是每次结果不一定一样

代码部分

package com.java.video.mkv;import lombok.extern.slf4j.Slf4j;import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;/*** @Description:* @Author: tutu-qiuxie* @Create: 2026/4/29 23:33*/@Slf4j
public class UnFairLockTest002 {private static final ReentrantLock lock = new ReentrantLock(false);private static AtomicInteger order = new AtomicInteger(0);public static void main(String[] args) {log.info("========== 启动测试(非公平锁)==========");// 线程1:持有锁new Thread(() -> {log.info("[线程-1] 尝试获取锁");lock.lock();int current = order.incrementAndGet();log.info("🎯 [{}] 获取锁顺序 = {}", Thread.currentThread().getName(), current);try {log.info("[线程-1] ✅ 获取锁成功,执行3秒");printState("线程-1持锁中");sleep(3000);} finally {log.info("[线程-1] 🔓 即将释放锁");lock.unlock();log.info("[线程-1] 🔓 已释放锁");printState("线程-1释放后");}}, "线程-1").start();sleep(100);// 线程2~6:进入队列竞争for (int i = 2; i <= 6; i++) {int id = i;new Thread(() -> {log.info("[线程-{}] 👉 尝试加锁(进入竞争)", id);printState("线程-" + id + "进入前");lock.lock();int current = order.incrementAndGet();log.info("🎯 [{}] 获取锁顺序 = {}", Thread.currentThread().getName(), current);try {log.info("[线程-{}] 🎯 获取锁成功", id);printState("线程-" + id + "持锁中");sleep(500);} finally {lock.unlock();log.info("[线程-{}] 🔓 ------------------------------------------------------>释放锁", id);}}, "线程-" + i).start();}// 插队线程(关键观察点)for (int c=0;c<=2;c++){new Thread(() -> {// 等待锁释放瞬间
//                while (true) {
//                   // sleep(1);
//                    if (!lock.isLocked()) {
//                        if (lock.tryLock()) {
//                            break;
//                        }
//                    }
//                }// 这一刻:锁刚释放log.info("🔥 插队线程发现锁刚释放,开始抢锁");lock.lock();try {log.info("🔥 插队线程:{} 🎯 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~获取锁成功",Thread.currentThread().getName());printState("插队线程持锁");} finally {lock.unlock();log.info("🔥 插队线程-{} 🔓 *****************************************************************************释放锁",Thread.currentThread().getName());}}, "插队线程"+c).start();}}/*** 打印 AQS 状态(关键观测点)*/static void printState(String tag) {log.info("---- [{}] AQS状态 ----", tag);log.info("队列是否有等待线程: {}", lock.hasQueuedThreads());log.info("队列长度: {}", lock.getQueueLength());log.info("是否有人持有锁: {}", lock.isLocked());log.info("----------------------");}static void sleep(long ms) {try {Thread.sleep(ms);} catch (InterruptedException ignored) {}}}

  

公平锁:先来后到,按排队顺序执行
非公平锁:谁抢到谁先执行(允许插队)

  

ReentrantLock fairLock = new ReentrantLock(true);  // 公平锁ReentrantLock unfairLock = new ReentrantLock(false); // 非公平锁(默认)

  

公平锁特点:
按等待队列顺序获取锁
不允许插队
更“规矩”优点:公平,不会饿死线程
缺点:性能较低(需要排队检查)

  

✔ 非公平锁(默认)特点:
新线程可能直接抢锁成功
不一定按顺序优点:
性能更高(少排队)
吞吐量更大缺点:
可能“后来的先执行”
极端情况下某些线程会等待更久

  

image

 

http://www.jsqmd.com/news/728274/

相关文章:

  • YOLOv5-Lite网络结构拆解:ShuffleNetV2的‘四条黄金法则’是如何被巧妙应用的?
  • 【VMware Workstation】Debian 13 安装 sing-box(Claaash配置转换sing-box配置)
  • 简述C++的复杂性
  • 手把手教你用TI AWR2944毫米波雷达Demo:从硬件连接到实时点云可视化(含TI Gallery工具配置)
  • RNN隐状态机制解析
  • 2026届必备的六大AI写作工具横评
  • L-Shape方法避坑指南:为什么你的两阶段随机规划模型不收敛?
  • Joplin CLI工具:为AI Agent打造毫秒级笔记操作方案
  • 从PID调参到SVPWM:深入理解SimpleFOC中voltage_limit参数设置的坑
  • 别再用画图软件了!5分钟学会用SMILES字符串搞定分子结构(附SwissADME实战)
  • 北京陪诊服务行业规范化发展提速 头部机构构建专业服务新标杆 - 品牌排行榜单
  • 智能体框架设计:从任务规划到工具调用的工程实践
  • 开箱即用:REX-UniNLU镜像一键启动,打造个人语义分析工作站
  • epoll 反应堆模型深度拆解:从红黑树到回调闭环,手写高性能回射服务器
  • Pix2Text:你的智能文档扫描仪,让图片中的数学公式和表格“开口说话“
  • 随身WIFI变随身服务器:Docker+青龙面板+SSH远程访问保姆级配置指南
  • RustClaw:轻量级AI Agent框架,7.5MB实现高效自动化与记忆管理
  • 魔兽争霸3卡顿终结者:3分钟学会用WarcraftHelper让老游戏焕发新生
  • 创业公司如何借助Taotoken快速集成多模型能力并控制成本
  • douyin-downloader:抖音无水印批量下载的技术实现与工程实践
  • 什么是物料管理erp系统?深度解析物料管理erp系统的功能与应用
  • 强化学习与流动力学结合优化LLM训练
  • 别再手动查日志了!用Prometheus+vmware_exporter给你的VMware vSphere做个全身体检(附K8s/Docker两种部署避坑指南)
  • ScottPlot 5.0配色与样式终极指南:让你的C# WinForm图表告别“土味”(含颜色库封装)
  • 微软发布 PC - DOS 1.00 源代码:追溯操作系统起源,洞察开发历史!
  • 对比使用Taotoken前后在模型选型与成本管理上的变化
  • 用Python做个大学财务小助手:5分钟搞定助学贷款额度计算(附完整代码)
  • CC-Switch 超详细入门教程附安装包(Windows/macOS/Linux)
  • 基于向量数据库与LLM的本地智能文件检索系统部署指南
  • 保姆级教程:C# WinForm配合S7.net库,批量读写200 SMART PLC的IO点和寄存器