JAVA中的一些锁概念

乐观锁和悲观锁

乐观锁:这个锁认为出现锁竞争的概率比较低(当前线程中,线程数量较少,不太涉及竞争,就偶尔竞争一下)
悲观锁:这个所认为出现锁竞争的概率比较大(当前场景中,线程数目比较多,可能涉及竞争)

读写锁

普通的锁提供两个操作:加锁,解锁
读写锁提供三个操作:读加锁,写加锁,解锁。
读加锁和读加锁:不需要互斥
写加锁和写加锁之间:需要互斥
读加锁和写加锁之间:需要互斥
主要适用于读多写少的场景

重量解锁和轻量级锁

从工作量来区分:
重量级锁,工作量更多,消耗资源更多,锁更慢
轻量级锁,工作量更少,消耗资源少,锁更快
操作系统中的mutex就是一个重量级锁(也是悲观锁),这个锁在加锁的时候就会遇到冲突,就会产生内核态和用户态的切换,以及线程的调度和阻塞。

自旋锁

在加锁的时候遇到冲突,不会涉及到用户态和内核态的切换,直接尝试重新获取锁。
会一直在循环中尝试获取锁,直到获取成功,这个过程中没有放弃cpu,不涉及线程调度。

公平锁和非公平锁

在这里插入图片描述

什么叫公平?
就是先来先服务。
如果不是按照先来后到的方式获取锁,就是非公平锁。

可重入锁和不可重入锁

一个线程对于相同的一把锁连续加锁两次。
对于不可重入锁:就会有问题
对于可重入锁:可以充入
例如:我们常用的synchronized就是可重入锁
因为synchronized的底层有一个计数器,当你对同一个对象连续加锁几次后,它的计数器就会加几次,解锁的时候,计数器就会–。

死锁

当产生死锁之后,就无法继续往下工作了(严重BUG)
死锁产生的原因:产生环路等待。
死锁的危害:线程无法继续工作。
避免死锁:1.不要在加锁的代码中在尝试获取其他锁;2.约定一定的顺序获取其他锁。
在这里插入图片描述

CAS(compare and swap)比较并交换

在这里插入图片描述
java中AtomicInteger中的自增方法就可以看出来,如果Var1对象中的值和var2是相等的,就可以将var1的值更新。如果不是,就会一直自旋。
随着CAS的出现就会有ABA问题
什么是ABA问题呢?
举个栗子:ABA问题就是你买了个新手机你不知道这个手机是新机还是翻新机。
画个抽象一点图在解释一下:
在这里插入图片描述
那怎么解决ABA问题呢?
答案是加个版本号!!!
在这里插入图片描述

synchronized的锁升级过程

具体逻辑是这样的:
无锁状态-偏向锁-轻量级锁-重量级锁
第一个线程加锁的时候,并不是真正意义上的加锁,而是设置了一个标记位。
当第二个线程也来访问同一个变量的时候,第一个线程才是真正意义上的加锁,第二个线程也会加锁。这就从偏向锁转向了轻量级锁,随着相乘越来越多,因为轻量级锁内部是自旋锁,多个线程的情况下也不容易立马获取到锁,这时吃cup就越来越严重,慢慢的就转变成了重量级锁,此时没获取到锁的线程转变为内核态,进行阻塞。

  • 2
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值