news 2026/5/1 11:25:51

Java中的锁机制总结

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java中的锁机制总结

文章目录

    • 一、锁的基本概念:为什么需要锁?
    • 二、锁的分类体系
    • 三、核心锁机制深度剖析
      • 1. 悲观锁 vs 乐观锁
      • 2. synchronized的锁升级过程
      • 3. 读写锁(ReadWriteLock)
      • 4. 自旋锁
    • 四、数据库锁机制
      • 1. 行锁 vs 表锁
      • 2. 间隙锁(Gap Lock)与临键锁(Next-Key Lock)
      • 3. 意向锁
    • 五、分布式锁:超越单机范畴
      • 1. 基于Redis的分布式锁
      • 2. 基于Zookeeper的分布式锁
    • 六、实战案例:转账业务中的锁应用
    • 七、避坑指南与最佳实践
    • 八、总结
    • 参考文章

大家好,我是你们的技术老友科威舟,今天给大家分享一下Java中的锁机制。

技术干货满满,一文带你了解Java中的锁。

在并发编程的世界里,锁是保障线程安全的重要工具。但面对琳琅满目的锁机制,很多开发者都会感到困惑。今天,我们将深入剖析Java中的各种锁机制,带你打通并发编程的"任督二脉"。

一、锁的基本概念:为什么需要锁?

在多线程环境下,多个线程同时访问共享资源会导致数据竞争问题。锁作为一种同步机制,可以确保同一时间只有一个线程能够访问共享资源,从而保证数据的一致性。

可以把锁想象成卫生间钥匙:当一个使用者拿到钥匙进入卫生间时,其他人必须等待;使用完毕后归还钥匙,下一个人才能使用。这种机制避免了尴尬的"撞车"情况。

二、锁的分类体系

Java中的锁可以按照不同的维度进行分类,让我们通过一个表格全面了解锁的家族体系:

分类维度锁类型典型实现特点
锁的性质悲观锁synchronized, ReentrantLock认为会发生并发冲突,先加锁再访问
乐观锁CAS, AtomicInteger认为不会发生冲突,先修改再检查
锁的粒度表锁数据库表锁锁定整张表,粒度粗
行锁数据库行锁锁定特定行,粒度细
读写特性读写锁ReentrantReadWriteLock读共享,写独占
排它锁synchronized, ReentrantLock完全独占
锁状态偏向锁synchronized优化偏向第一个访问线程
轻量级锁synchronized优化CAS实现,避免线程阻塞
重量级锁synchronized最终形态基于操作系统互斥量
等待机制自旋锁CAS自旋循环尝试获取锁
范围意向锁数据库意向锁表明"意图"加行级锁

三、核心锁机制深度剖析

1. 悲观锁 vs 乐观锁

悲观锁就像一位过度谨慎的管家,总是假设最坏情况——认为每次访问共享资源时都会有其他线程修改数据。因此,它在操作前总会先加锁。

// 悲观锁示例 - synchronizedpublicsynchronizedvoidtransferMoney(Accountfrom,Accountto,doubleamount){// 转账逻辑from.withdraw(amount);to.deposit(amount);}

乐观锁则像一位乐观的协调者,假设操作期间不会发生冲突,只在提交时检查数据是否被修改。

// 乐观锁示例 - CASpublicclassOptimisticLockExample{privateAtomicIntegerbalance=newAtomicInteger(100);publicbooleanwithdraw(intamount){intcurrent;do{current=balance.get();if(current<amount){returnfalse;}}while(!balance.compareAndSet(current,current-amount));returntrue;}}

适用场景:悲观锁适合写多读少的高冲突场景;乐观锁适合读多写少的低冲突场景。

2. synchronized的锁升级过程

synchronized的优化过程就像职场新人的成长路径

偏向锁(新人期):当只有一个线程访问时,JVM会偏向这个线程,后续访问无需同步操作。这就像部门里只有一个员工,所有资源都优先给他使用。

轻量级锁(成长期):当有轻微竞争时,线程通过CAS操作尝试获取锁,避免线程阻塞。如同几个同事协作,通过简单沟通就能解决问题。

重量级锁(成熟期):当竞争激烈时,锁升级为重量级锁,未获取到锁的线程会被阻塞。这就像重要项目需要正式会议和严格流程来协调资源。

3. 读写锁(ReadWriteLock)

读写锁采用了"多读单写"的策略,非常适合读多写少的场景。

publicclassReadWriteCache{privateMap<String,Object>cache=newHashMap<>();privateReadWriteLockrwLock=newReentrantReadWriteLock();publicObjectget(Stringkey){rwLock.readLock().lock();try{returncache.get(key);}finally{rwLock.readLock().unlock();}}publicvoidput(Stringkey,Objectvalue){rwLock.writeLock().lock();try{cache.put(key,value);}finally{rwLock.writeLock().unlock();}}}

这种设计允许多个读线程同时访问,但写线程独占访问,大大提高了系统的并发性能。

4. 自旋锁

自旋锁的理念是:如果锁的持有时间很短,那么等待锁的线程稍作循环等待(自旋)可能比挂起更高效

就像等电梯时,如果知道电梯马上就到,我们会选择在门口等待(自旋)而不是回工位(线程挂起)。

publicclassSpinLock{privateAtomicBooleanlocked=newAtomicBoolean(false);publicvoidlock(){// 自旋等待while(!locked.compareAndSet(false,true)){// 自旋期间可以执行一些轻量级操作}}publicvoidunlock(){locked.set(false);}}

但自旋锁要注意自旋时间,过长会浪费CPU资源。

四、数据库锁机制

1. 行锁 vs 表锁

行锁就像精确制导导弹,只锁定需要的数据行,其他行仍可正常访问。这提供了更好的并发性,但管理开销较大。

表锁则是范围轰炸,直接锁定整张表,管理简单但并发性差。

实战场景:在用户余额更新时使用行锁,避免全表锁定影响其他用户操作。

2. 间隙锁(Gap Lock)与临键锁(Next-Key Lock)

间隙锁锁定索引记录之间的间隔,防止幻读;临键锁则是行锁+间隙锁的组合。

比如,防止在事务执行过程中,有其他插入操作在条件范围内添加新记录。

3. 意向锁

意向锁是一种声明式锁,表示"我打算在这个资源上加更细粒度的锁"。这就像在会议室门口挂"预定"牌子,表明后续会详细使用。

五、分布式锁:超越单机范畴

在分布式系统中,单机锁已无法满足需求,我们需要分布式锁来协调多个节点。

1. 基于Redis的分布式锁

publicclassRedisDistributedLock{publicbooleantryLock(StringlockKey,StringrequestId,intexpireTime){returnredisTemplate.opsForValue().setIfAbsent(lockKey,requestId,expireTime,TimeUnit.SECONDS);}publicbooleanunlock(StringlockKey,StringrequestId){// 使用Lua脚本保证原子性Stringscript="if redis.call('get', KEYS[1]) == ARGV[1] then "+"return redis.call('del', KEYS[1]) else return 0 end";returnredisTemplate.execute(newDefaultRedisScript<Long>(script,Long.class),Collections.singletonList(lockKey),requestId)==1;}}

2. 基于Zookeeper的分布式锁

Zookeeper通过创建临时顺序节点实现公平的分布式锁,像银行排队机一样保证先来后到。

六、实战案例:转账业务中的锁应用

让我们通过一个完整的转账案例,展示不同锁的应用:

@ServicepublicclassTransferService{// 使用ReentrantLock保证账户操作的原子性privatefinalLocklock=newReentrantLock(true);// 公平锁@Transactionalpublicbooleantransfer(Accountfrom,Accountto,BigDecimalamount){if(lock.tryLock()){try{// 检查余额是否充足if(from.getBalance().compareTo(amount)>=0){from.debit(amount);to.credit(amount);accountRepository.save(from);accountRepository.save(to);returntrue;}}finally{lock.unlock();}}returnfalse;}}

在这个案例中,我们结合了数据库事务ReentrantLock余额检查,确保了转账操作的安全性和一致性。

七、避坑指南与最佳实践

  1. 死锁预防:避免嵌套锁,按固定顺序获取锁,使用定时锁
  2. 锁粒度:尽量减小锁的粒度,只锁定必要的代码块
  3. 锁分离:读写分离,使用ReadWriteLock替代独占锁
  4. 性能监控:关注锁竞争情况,避免不必要的锁升级

八、总结

Java的锁机制是一个庞大而精妙的体系,从简单的synchronized到复杂的分布式锁,每种锁都有其适用场景。合理选择和使用锁,是构建高并发应用的关键。

记住:没有最好的锁,只有最合适的锁。明智地选择锁策略,让你的应用在并发场景下游刃有余!

参考文章

  1. https://developer.aliyun.com/article/1441144
  2. https://blog.csdn.net/weixin_44817884/article/details/136677898
  3. https://blog.csdn.net/u013738122/article/details/105474728
  4. https://m.php.cn/zh-tw/faq/556205.html
  5. https://docs.pingcode.com/baike/275423
  6. https://docs.pingcode.com/baike/390005
  7. https://blog.51cto.com/u_16175498/13407976

希望这篇文章能帮助你更好地理解Java中的各种锁机制!如有疑问,欢迎留言讨论。


更多技术干货欢迎关注微信公众号科威舟的AI笔记~

【转载须知】:转载请注明原文出处及作者信息

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 10:03:13

市场快评 · 今日复盘要点20251217

Q1:今日是否适合低吸? A:今日上涨个股3626 家,大于2500家阈值, 市场情绪得到修复, 把仓位加到 60%。 Q2:昨日最高标今日表现如何? A:昨日最高标 百大集团 今日继续涨停。 3:今日主线题材及板块龙头是谁? A:主线为 智能驾驶,板块龙头 暂时看不出来,核心容量标的为…

作者头像 李华
网站建设 2026/4/30 15:04:26

强化学习围捕仿真系统优化方案

强化学习围捕仿真系统优化方案 一、问题分析与现状评估 1.1 当前问题分析 在强化学习围捕仿真任务中,主要存在以下核心问题: 速度劣势:围捕艇速度慢于目标,无法通过速度优势直接捕获 成功率极低:2万轮次仅成功20多次,成功率约0.1% 学习效率低下:算法未能有效学习到有…

作者头像 李华
网站建设 2026/5/1 9:14:37

筛选器管理模块 Cordova 与 OpenHarmony 混合开发实战

&#x1f4cc; 概述 筛选器管理模块允许用户保存和管理常用的筛选条件。该模块集成了 Cordova 框架与 OpenHarmony 原生能力&#xff0c;提供了完整的筛选器管理功能。用户可以创建多个筛选器&#xff0c;为每个筛选器设置特定的条件&#xff0c;然后快速应用这些筛选器来查看特…

作者头像 李华
网站建设 2026/5/1 1:58:54

每日统计模块 Cordova 与 OpenHarmony 混合开发实战

&#x1f4cc; 概述 每日统计模块提供了每日喝茶数据的统计分析功能。该模块集成了 Cordova 框架与 OpenHarmony 原生能力&#xff0c;实现了高效的数据统计和可视化展示。用户可以查看特定日期的喝茶记录总数、消费金额、平均评分等统计数据。模块支持日期范围选择和数据导出。…

作者头像 李华
网站建设 2026/5/1 10:29:52

AWS SageMaker SDK 完整教程:从零开始云端训练你的模型 _

一、SageMaker介绍Amazon SageMaker 是 AWS 提供的全托管机器学习平台&#xff0c;它覆盖了从数据准备、模型训练、超参数调优到模型部署的完整流程&#xff0c;我们可以通过 SageMaker&#xff0c;轻松创建 Notebook 实例进行数据探索和实验&#xff0c;也可以使用AWS的计算资…

作者头像 李华