【进阶之路】包罗万象——JAVA中的锁

导言大家好,我是南橘,从接触java到现在也有差不多两年时间了,两年时间,从一名连java有几种数据结构都不懂超级小白,到现在懂了一点点的进阶小白,学到了不少的东西。知识越分享越值钱,我这段时间总结(包括从别的大佬那边学习,引用)了一些平常学习和面试中的重点(自我认为),希望给大家带来一些帮助这是之前的几篇文章,有兴趣的同学可以看看(暗搓搓给自己打广告)索引中一些易忽视的点Redis...
摘要由CSDN通过智能技术生成

导言

大家好,我是南橘,从接触java到现在也有差不多两年时间了,两年时间,从一名连java有几种数据结构都不懂超级小白,到现在懂了一点点的进阶小白,学到了不少的东西。知识越分享越值钱,我这段时间总结(包括从别的大佬那边学习,引用)了一些平常学习和面试中的重点(自我认为),希望给大家带来一些帮助

这是之前的几篇文章,有兴趣的同学可以看看(暗搓搓给自己打广告)

在Java中,我们能接触到各种各样的锁,而每种锁因其特性的不同,在不同的的场景下有着不同的效果,这篇文章,就是为和大家一起学习这些锁的知识点、原理和使用范围。

这篇文章很多内容学习自 不可不说的Java“锁”事,也正是看了美团技术团队很多文章,才让自己的技术更加纯熟

有需要的同学可以加我的公众号,以后的最新的文章第一时间都在里面,也可以找我要思维导图

一、乐观锁 VS 悲观锁

悲观锁乐观锁大概是大家听到最多的两种锁了,这两种锁的区分更多的是思想上。

对于一个操作,悲观锁认为自己在操作过程中,一定有别的线程也要来修改这个数据,所以一定会加锁。而乐观锁则不认为会有别的线程来干扰自己,所以不需要加锁。

在Java中,synchronized关键字和Lock的实现类都是悲观锁,而乐观锁一般采用无锁编程,也就是CAS算法来实现的。

首先说一说悲观锁

1、悲观锁


悲观锁的流程:

  • 1、线程尝试去获取锁
  • 2、线程加锁成功并执行操作,其他线程等待,线程加锁失败则等待获取锁(这里有好几种办法,在synchronized中,会有在四种状态中改变,在下文中我会介绍这四种情况)
  • 3、线程执行完毕释放锁,其他线程获取锁

通过图片和文字,我们能看出悲观锁适合写操作多的场景,加锁可以确保数据的安全,但是会影响一些操作效率。

2、乐观锁

这两张图是从这位大佬的文章中引用的:不可不说的Java“锁”事 - 美团技术团队

乐观锁的流程:

  • 1、线程直接获取同步资源数据
  • 2、判断内存中的同步数据是否被其他线程修改
  • 3、没有被修改则直接更新
  • 4、如果被其他线程修则选择报错或者重试(自旋)

和悲观锁不同,乐观锁明显不适合经常进行修改,因为谁也不能保证不会出现数据安全的问题,所以乐观锁适合读操作的场景。对于读操作来说,加锁只会影响效率。

上文说到了,乐观锁一般采用CAS算法来实现,那么我们就来讲讲什么是CAS算法

3、CAS算法

CAS的英语是【Compare and Swap】,比较和交换,单单从这一个词组来看,我们就已经能Get到CAS算法的核心了。

感觉已经讲完了,就像之前去面菜鸟的时候,面试官哥哥问我:“TCP和UDP的区别是什么”。我下意识地说了一句,一个是单工通信,一个是双工通信。停顿了一下,准备继续洋洋洒洒的时候,面试官严肃地直接打断了我:“可以了。”

CAS的算法涉及三个操作数: 内存位置(V)、预期原值(A)和新值(B)。

如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。否则,处理器不做任何操作。无论哪种情况,它都会在 CAS 指令之前返回该位置的值。

换一种说法,当且仅当 V 的值等于 A时,CAS通过原子方式用新值B来更新V的值(“比较+更新”整体是一个原子操作),否则不会执行任何操作。

在JDK1.5 中新增java.util.concurrent(J.U.C)就是通过实现CAS来实现乐观锁的。
我们可以看一下它的重点:

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值