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

Java多线程同步方法ReentrantLock显式锁实现方式

一、基本使用方式

  1. 显式获取与释放锁

    • 声明锁对象:通常使用final修饰ReentrantLock实例,避免外部修改导致锁状态异常。
    • 加锁与解锁:需手动调用lock()unlock()方法,且unlock()必须放在finally块中,确保异常时锁仍能释放。
      public class SharedData {private final ReentrantLock lock = new ReentrantLock();public void accessData() {lock.lock();  // 显式获取锁try {// 临界区代码} finally {lock.unlock();  // 显式释放锁}}
      }
      
    • 关键点:若在lock()try之间插入代码(如日志记录),需确保不会抛出异常,否则unlock()可能未执行,导致锁泄漏。
  2. 锁的可重入性

    • 同一线程可多次获取同一把锁,释放次数需与获取次数匹配。
      public void nestedLock() {lock.lock();try {lock.lock();  // 允许重入try { ... }finally { lock.unlock(); }  // 第二次释放} finally { lock.unlock(); }    // 第一次释放
      }
      
    • 此特性避免了线程在递归或嵌套调用中因重复加锁导致的死锁。

二、公平性与非公平性

  1. 构造函数参数

    • 通过ReentrantLock(boolean fair)指定公平策略:
      • 公平锁(fair=true):按请求顺序分配锁,减少线程饥饿,但可能降低吞吐量。
      • 非公平锁(默认):允许插队获取锁,性能更高,但可能引发饥饿。
  2. 适用场景

    • 高并发场景下优先使用非公平锁;需保证公平性(如资源分配)时选择公平锁。

三、高级特性

  1. 尝试加锁与超时机制

    • 尝试非阻塞加锁:tryLock()方法立即返回是否成功获取锁,避免线程阻塞。
    • 带超时的尝试加锁:tryLock(long timeout, TimeUnit unit)在指定时间内尝试获取锁,超时后返回false
      if (lock.tryLock(1, TimeUnit.SECONDS)) {try { ... }finally { lock.unlock(); }
      }
      
  2. 条件变量(Condition)

    • 通过newCondition()创建多个条件队列,实现多条件等待与通知。
    • 示例:生产者-消费者模式中,不同条件(如“数据已满”和“数据为空”)可分别管理。
      ReentrantLock lock = new ReentrantLock();
      Condition notEmpty = lock.newCondition();
      Condition notFull = lock.newCondition();
      // 生产者线程
      lock.lock();
      try {while (queue.size() >= CAPACITY) {notFull.await();  // 等待队列不满}queue.add(item);notEmpty.signal();    // 通知消费者
      } finally { lock.unlock(); }
      // 消费者线程
      lock.lock();
      try {while (queue.isEmpty()) {notEmpty.await();  // 等待队列非空}item = queue.remove();notFull.signal();     // 通知生产者
      } finally { lock.unlock(); }
      
    • 相比synchronizedwait/notifyCondition支持更细粒度的线程协作。

四、性能优化与注意事项

  1. 性能对比
    • 在低竞争场景下,synchronized因JVM优化(如偏向锁)可能更快;高竞争场景下,ReentrantLock的可控制性更优。
    • ReentrantLock的显式锁释放机制减少了线程上下文切换的开销。
  2. 常见问题
    • 锁泄漏:忘记调用unlock()会导致其他线程永久阻塞,需严格使用finally块。
    • 死锁:嵌套锁需确保获取顺序一致,或使用超时机制避免无限等待。

五、与synchronized的对比

特性ReentrantLocksynchronized
加锁方式显式(需手动调用lock/unlock隐式(编译器自动处理)
锁粒度可指定任意对象锁方法或代码块(基于对象实例)
公平性支持公平与非公平模式仅非公平
条件变量支持多条件队列仅单条件(wait/notify
性能高竞争场景更优低竞争场景更优

六、适用场景

  1. 需要精细控制锁行为:如超时加锁、多条件等待。
  2. 高并发系统:通过非公平锁优化吞吐量。
  3. 复杂业务逻辑:可重入性避免递归调用中的死锁风险。
    通过合理使用ReentrantLock的显式锁机制,开发者可在多线程环境中实现高效、灵活的同步控制。
http://www.xdnf.cn/news/5289.html

相关文章:

  • Python数据分析
  • Spring 6.x 详解介绍
  • 【从零实现JsonRpc框架#1】Json库介绍
  • 基于NI-PXI的HIL系统开发
  • MySQL 1366 - Incorrect string value:错误
  • MySQL:视图
  • 串口屏调试 1.0
  • ComfyUI 如何安装ComfyUI_SLK_joy_caption_two
  • window环境下,如何通过USB接口控制打印机
  • 质心均匀体(引力屏蔽技术)
  • 算法训练营第十三天|226.翻转二叉树、101. 对称二叉树、 104.二叉树的最大深度、111.二叉树的最小深度
  • 多模态大模型中的视觉分词器(Tokenizer)前沿研究介绍
  • 【入门】数字走向II
  • JavaScript 数组去重:11 种方法对比与实战指南
  • 什么是 B2B?2B 产品销售怎么找客户?
  • Unity基础学习(十)Camera组件
  • [ctfshow web入门] web67
  • JVM对象创建内存分配
  • [特殊字符]️ 快速检测与修复TLS 1.0/1.1漏洞指南
  • 人形机器人:主控芯片
  • 红黑树算法笔记(二)性能对比实验
  • 解密数据结构之位图和布隆过滤器
  • TCP IP
  • 社区商城分销团长扩充与扩散策略优化的系统方案
  • Information Fusion期刊期刊投稿经验分享
  • 23、DeepSeekMath论文笔记(GRPO)
  • 计算机网络与多线程同步机制详解
  • Linux系统之----模拟实现shell
  • 轻量级因果语言视觉模型简述:nanoVLM-222M
  • 每日一题:两个仓库的最低配送费用问题