当前位置: 首页 > 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,每种锁都有其适用的场景和优势。在选择锁的实现方式时,开发者需要根据实际的业务需求、并发量、性能要求等因素做出合理的选择。

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

相关文章:

  • LeetCode算法题(Go语言实现)_51
  • Vue3如何选择传参方式
  • C++面试
  • 【HDFS入门】HDFS核心配置与优化指南概述
  • 【Python学习笔记】Pandas实现Excel质检记录表初审、复核及质检统计
  • webgl入门实例-08索引缓冲区的基本概念
  • 杂记-LeetCode中部分题思路详解与笔记-HOT100篇-其三
  • 二分查找-LeetCode
  • 代码学习总结(三)
  • 算法5-16 对二进制字符串解码
  • 多 Agent 协作怎么整:从谷歌A2A到多Agent交互方案实现
  • STL简介(了解)
  • 【无标题】
  • Qt核心知识总结
  • 第六章:6.3求一个3*3的整型矩阵对角线元素之和
  • ESP32-idf学习(二)esp32C3作服务端与电脑蓝牙数据交互
  • 机器学习有多少种算法?当下入门需要全部学习吗?
  • vscode+keil嵌入式软件开发全流程
  • C++笔记-list
  • 【已更新】2025华中杯C题数学建模网络挑战赛思路代码文章教学数学建模思路:就业状态分析与预测
  • 06-DevOps-自动构建Docker镜像
  • 动态规划专题5:最长上升子序列
  • LeetCode hot 100—括号生成
  • 数据中台(大数据平台)之数据质量管理
  • 3.Rust + Axum 提取器模式深度剖析
  • 【Python Cookbook】迭代器与生成器(一)
  • 【Qt】初识Qt(一)
  • Oracle 12.1.0.2补丁安装全流程
  • FPGA阵列
  • ZStack文档DevOps平台建设实践