Java中的锁

在这里插入图片描述

乐观锁:认为自己在使用数据时不会有别的线程修改数据,所以不会添加锁,只是在更新数据的时候去判断之前有没有别的线程更新了这个数据。(CAS算法,AtomicInteger类的院子自增是通过CAS自旋实现)
1 适用场景:多操作较多,不加锁的特点能够使读的性能大大提高。
2 执行流程
在这里插入图片描述
悲观锁:认为自己使用数据的时候一定有别的线程来修改数据,在获取数据的时候会先加锁,确保数据不会被别的线程修改。(synchronized Lock )
1 使用场景:写操作数据比较多,先加锁可以保证写操作时数据正确。
2 执行流程
无锁等待,有锁执行(获取CPU的权限)
在这里插入图片描述
CAS算法
无锁算法:基于硬件原语实现,在不使用锁的情况下实现多线程直线的变量同步。
jdk中实现:java.util.concurrent包中的原子类(AtomicInteger)就是通过CAS实现乐观锁
算法涉及到三个操作数:
需要读写的内存值 V
进行比较的值 A
要写入的新值 B
在这里插入图片描述在这里插入图片描述
下面的就是自旋的操作,设置值的时候,发现始终对不上的话就一直自旋(取值然后在比较值)
在这里插入图片描述
CAS存在的问题
在这里插入图片描述
线程更新了主内存中的V值,假设有第三个线程进来,读取到A的值为1,B的值也为0 ,线程3 比线程2 先更新了主内存的值。线程2 来比较发现认为主内存区的值没有发生过状态改变。这时候也能修改成功,并不能侦测到线程3的修改操作。相当于喝了一杯水,又把水倒满杯子。
ABA问题已经解决了:AtomicStampedReference在变量前面添加版本号,每次变量更新的时候都版本号加一。
只能保证一个变量的原子操作问题已经解决了:AtomicReference类来保证引用对象之间的原子性,可以把多个变量放在一个对象里来进行CAS操作。

自旋锁
指当一个线程在获取锁的时候,如果已经被其他线程获取,那么该线程将循环等待,然后不断的判断锁是否你能够被成功的获取,自旋知道获取到锁才能退出循环。
1.阻塞与唤醒线程需要操作系统切换CPU状态,需要消耗一定时间
2.同步代码块逻辑简单,执行时间短
在这里插入图片描述
公平锁与非公平锁:
工具类:java.util.concurrent.locks包下面:
基于实现Lock锁的机制的ReentrantLock(实现了Lock 和Sericlizable)
公平锁:
在这里插入图片描述
非公平锁:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值