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

ReentrantLock

与 synchronized的异同点:

相同:都支持可重入

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

@Slf4j(topic = "c.TestReentrant")
public class TestReentrant {static ReentrantLock lock = new ReentrantLock();public static void main(String[] args) {method1();}public static void method1() {lock.lock();try {log.debug("execute method1");method2();} finally {lock.unlock();}}public static void method2() {lock.lock();try {log.debug("execute method2");method3();} finally {lock.unlock();}}public static void method3() {lock.lock();try {log.debug("execute method3");} finally {lock.unlock();}}
}

不同:对于 synchronized它具备如下特点

可中断

两个线程同时去争一把锁的情况下,可以避免让没获取到的一直处于等待状态

lockInterruptibly()

demo如下:

package concurrent.reentrantlock;import lombok.extern.slf4j.Slf4j;import java.util.concurrent.locks.ReentrantLock;import static util.Sleeper.sleep;@Slf4j(topic = "c.TestInterrupt")
public class TestInterrupt {public static void main(String[] args) {test2();}private static void test2() {ReentrantLock lock = new ReentrantLock();Thread t1 = new Thread(() -> {log.debug("启动...");lock.lock();try {log.debug("获得了锁");} finally {lock.unlock();}}, "t1");lock.lock();log.debug("获得了锁");t1.start();try {sleep(1);t1.interrupt();log.debug("执行打断");sleep(1);} finally {log.debug("释放了锁");lock.unlock();}}private static void test1() {ReentrantLock lock = new ReentrantLock();Thread t1 = new Thread(() -> {log.debug("启动...");try {lock.lockInterruptibly();} catch (InterruptedException e) {e.printStackTrace();log.debug("等锁的过程中被打断");return;}try {log.debug("获得了锁");} finally {lock.unlock();}}, "t1");lock.lock();log.debug("main 获得了锁");t1.start();try {sleep(1);t1.interrupt();log.debug("main 执行打断");} finally {lock.unlock();}}
}
可以设置超时时间
tryLock(1, TimeUnit.SECONDS)
package concurrent.reentrantlock;import lombok.extern.slf4j.Slf4j;import java.util.concurrent.locks.ReentrantLock;import static util.Sleeper.sleep;@Slf4j(topic = "c.TestInterrupt")
public class TestInterrupt {public static void main(String[] args) {test1();}private static void test2() {ReentrantLock lock = new ReentrantLock();Thread t1 = new Thread(() -> {log.debug("t1 启动...等锁中");lock.lock();try {log.debug("获得了锁");} finally {lock.unlock();}}, "t1");lock.lock();log.debug("获得了锁");t1.start();try {sleep(1);t1.interrupt();log.debug("执行打断");sleep(1);} finally {log.debug("释放了锁");lock.unlock();}}private static void test1() {ReentrantLock lock = new ReentrantLock();Thread t1 = new Thread(() -> {log.debug("启动...");try {lock.lockInterruptibly();} catch (InterruptedException e) {e.printStackTrace();log.debug("等锁的过程中被打断");return;}try {log.debug("获得了锁");} finally {lock.unlock();}}, "t1");lock.lock();log.debug("main 获得了锁");t1.start();try {sleep(1);t1.interrupt();log.debug("main 执行打断");} finally {lock.unlock();}}
}
可以设置为公平锁

公平锁一般没有必要,会降低并发度;可以使用tryLock()去设置超时时间。

支持多个条件变量

送烟、送外卖的例子;

多个条件变量,对应多个等待区;

Demo

http://www.xdnf.cn/news/3823.html

相关文章:

  • C语言-回调函数
  • 大客户销售大客户营销50个常见概念及其英文表达。AI大客户销售B2B大客户营销关键概念集合
  • 全参数解读Qwen 3 系列模型 + 本地部署实操 + 多维度能力深度测评
  • 计算机总线系统入门:理解数据传输的核心
  • 动态功耗与静态功耗
  • 从零开始理解 C++ 后端编程中的分布式系统
  • Runnable组件重试机制降低程序错误率
  • 深度解析ComfyUI的使用
  • Linux常用命令29——delgroup删除组
  • Spring IoC 注解式开发全解析
  • Java面试资源获取
  • vmware diffy配置ollama 本机ip无法访问
  • AI 大模型常见面试题(及内容解析)
  • ip和域名
  • BUUCTF——禁止套娃
  • 【Hot 100】94. 二叉树的中序遍历
  • Spring 命名空间注入:p、c 与 .util 的深度解析
  • 欧拉计划 Project Euler64(奇周期平方根)题解
  • C++抽象基类三重防线:纯虚函数与保护构造的深度实践
  • js单调栈解题模板
  • skynet.socket.recv 没有处理分包问题
  • 办公文档全能处理工具功能解析
  • GR00t 安装使用教程踩坑记录
  • 专为焦油介质打造:煤焦油专用气动硬密封调节 V 型球阀(带手动)的卓越特点-耀圣
  • mvvm 如何 实现 MultiBinding 与转换器
  • SCAU18124--N皇后问题
  • 基于Vue2 + Element 实现任务列表管理功能的详细教程
  • tp5 php获取农历年月日干支甲午
  • MCP协议的使用分享
  • 数据库=====