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

Java锁的分类与解析

在多线程编程中,锁是确保共享资源不会同时被多个线程访问的关键工具。Java 提供了多种锁的实现方式,可以根据不同的需求选择适合的锁。本文将从多个维度对 Java 的锁进行分类,并对每种锁的特性进行详细解析。

锁的分类

锁的分类并没有唯一标准,而是取决于观察的角度或划分的维度。从不同维度出发,可以对锁进行多种类型的划分。以下是基于常见特性(如互斥性、重入性、公平性等)的一些主流分类方式,供参考。

1. 锁的基本对比

锁名(例子)重入性互斥性公平性分布式性实现方式适用场景
synchronized可重入独占非公平(不可配置)隐式锁基础同步,语法简单,低并发场景
ReentrantLock可重入独占公平 / 非公平(默认非公平)显式锁替代 synchronized,控制更灵活
ReadWriteLock可重入写独占 / 读共享公平 / 非公平(默认非公平)显式锁读多写少,读写分离
StampedLock不可重入写独占 / 读共享非公平(不可配置)显式锁高性能读多写少,需谨慎使用不可重入
Redis 分布式锁不支持(除非设置标志)独占非公平(不可配置)显式锁分布式场景下的互斥控制(使用 Redisson 等库)
Zookeeper 分布式锁不支持(除非设置标志)独占非公平(不可配置)显式锁分布式场景下的互斥控制(使用 Curator 等库)

2. 锁的类型与特性分析

2.1 重入性(同一线程)

  • 可重入锁:同一线程如果已经持有锁,【再次请求该锁不会】导致阻塞或死锁。例如,ReentrantLock 支持重入,即线程可以在持有锁的情况下再次请求锁。
  • 不可重入锁:同一线程如果已经持有锁,【再次请求该锁会】导致线程被阻塞,直到该锁被释放。StampedLock 就是不支持重入的锁。

2.2 互斥性(多线程)

  • 独占锁:同一时刻【只有一个线程】可以获取锁,其他线程必须等待锁被释放才能获得锁。这种锁适用于需要保证资源不被并发访问的场景。
  • 共享锁:同一时刻【多个线程】可以获取锁,通常适用于【读操作】。例如,ReadWriteLock 提供了共享锁,允许多个线程同时读取共享数据,但写操作是独占的。

2.3 公平性(多线程)

  • 公平锁:按照线程请求的【时间先后顺序分配锁】,避免某些线程长时间得不到锁,避免饥饿现象。例如,ReentrantLock 可以配置为公平锁。
  • 非公平锁:锁释放后,所有线程尝试【竞争锁】,谁先获得锁由线程调度决定,【不按请求时间先后顺序分配】。这可能导致部分线程长时间等待。synchronized 与默认的 ReentrantLock 属于非公平锁。

2.4 分布式性(多进程)

  • 分布式锁:分布式锁是用于【多个进程】之间实现互斥访问的锁,确保在分布式系统中不同进程对共享资源的访问是互斥的。分布式锁通常依赖外部的分布式协调系统来实现,如 ZookeeperRedisetcd 等。
  • 非分布式锁:非分布式锁是只在【单个进程】内使用的锁,主要用于控制同一进程中的多个线程之间的访问互斥。它无法跨进程或跨节点进行资源同步,限制了它的适用范围。

2.5 实现方式(锁管理主体)

  • 隐式锁:锁的管理由【系统(如 JVM)】自动完成控制锁的获取和释放。synchronized 是最典型的隐式锁,开发者仅通过简单的代码块来控制同步。
  • 显式锁:锁的管理由开发者通过明确的代码控制,通常是通过实现 Lock 接口的类来控制锁的获取与释放,【开发者】必须显式地控制锁的获取与释放。ReentrantLockReadWriteLock 是典型的显式锁。

3. 锁的应用场景

  • 基础同步synchronized 适用于简单的同步需求,语法简洁,但在高并发场景下可能不够灵活。
  • 灵活控制ReentrantLock 提供了更高的灵活性,可以指定锁的公平性,支持条件变量等功能。
  • 读多写少ReadWriteLock 适用于读多写少的场景,可以提升读操作的并发度。
  • 高性能场景StampedLock 适用于对性能要求较高的场景,尤其是在读多写少的环境下。
  • 分布式锁RedisZookeeper 分布式锁适用于分布式环境中的互斥控制,确保分布式系统中的数据一致性。

总结

Java 提供了多种类型的锁来满足不同场景下的并发需求。从 synchronizedReentrantLock,再到分布式锁如 RedisZookeeper,每种锁都有其适用的场景和优势。在选择锁的实现方式时,开发者需要根据实际的业务需求、并发量、性能要求等因素做出合理的选择。

相关文章:

  • QT6 源(34):随机数生成器类 QRandomGenerator 的源码阅读
  • 科学护理进行性核上性麻痹,缓解病痛提升生活质量
  • 用cython将python程序打包成C++动态库(windows+Vistual Studio2017平台)
  • Lombok @Builder 注解的进阶玩法:自定义 Getter/Setter 方法全攻略
  • 在没有第三方库的情况下使用 Python 自带函数解码
  • 3.串口通信之SPI
  • Java学习手册:Java内存模型
  • 22、字节与字符的概念以及二者有什么区别?
  • 【Python爬虫基础篇】--1.基础概念
  • MCP Server和Client的基本使用方法
  • halcon模板匹配(八)alignment_for_ocr_in_semiconductor
  • OCR:开启文档抽取的智能变革之门
  • 4.16 AT好题选做
  • 探索关系型数据库 MySQL
  • LFI to RCE
  • DiffuRec: A Diffusion Model for Sequential Recommendation
  • 将二进制的stl文件转换为ascii的形式
  • stm32F103、GD32F103读写Nor Flash实战指南
  • 吉利矩阵(DFS)
  • [AI]浅谈大模型应用开发的认知构建
  • 香港警务处高级助理处长叶云龙升任警务处副处长(行动)
  • 玉渊谭天丨中方减少美国农产品进口后,舟山港陆续出现巴西大豆船
  • 影子调查|23岁男子驾照拟注销背后的“被精神病”疑云
  • 财政部下达农业生产防灾救灾资金3.76亿元,支持黄淮海等地抗旱保春播
  • 李在明当选韩国共同民主党总统候选人
  • 持续更新丨伊朗内政部长:港口爆炸已致14人死亡