Java锁

公平锁
多个线程按照申请锁的顺序来获得锁;先检查等待队列是否为空,然后再CAS修改锁的状 态。
非公平锁
当一个线程申请锁时,如果锁处于空闲状态就直接获取锁,否则进入阻塞队列。直接CAS修改锁的状态,如果失败就进入等待队列。

读写锁
写锁被获取时,后续所有的读锁和写锁都会被阻塞。

自旋锁
线程获取锁时,会自旋一段时间等待锁的释放,而不是进入阻塞队列,一般有时间限制;
自适应自旋锁
线程的等待时间由上一次用于该锁的自旋时间和持有者状态决定。

可重入锁
能够支持一个线程对资源的重复加锁,例如一个线程在进行递归操作时可重复获取该锁,重复获取时其标志位加1;
非可重入锁
不支持一个线程对资源的重复加锁。

无锁
所有线程都能访问修改同一资源,但只有一个会修改成功,失败的会循环尝试,基于CAS原理。
偏向锁
如果一个锁一直被一个线程申请,这个线程就会自动获取该锁,而无需申请。会在对象头或栈帧中记录获取锁的进程的ID,再获取时,如果ID相同,就不用加锁和解锁;如果没有储存进程ID,就先看偏向锁的标志是否为1(判断该锁是否为偏向锁),为1就用CAS获取该锁,为0就使用CAS竞争该锁。
偏向锁只有在其他线程尝试竞争时,才会释放锁。当其他线程竞争时,它会等到全局安全点时暂停拥有锁的线程,如果线程还活着,就执行完之后给另一个线程或者将偏向锁升级为轻量级锁,不然就置为无锁状态。

优点:加锁和解锁不需要额外的消耗,适合一个线程访问一个代码块的场景
缺点:如果存在竞争,锁的撤销需要额外的消耗。

轻量级锁
将锁对象头的Mark Word复制到栈帧锁记录的空间中,然后使用CAS将Mark Word替换为指向锁记录的指针,如果失败就自旋等待。
锁撤销时使用CAS操作将锁记录复制回Mark Word中,如果失败,表示有其他线程竞争,锁就会膨胀为重量级锁。

优点:竞争的线程不会阻塞,提高了程序的响应速度,适用于代码块执行快,追求响应速度的场景;
缺点:线程会自旋消耗CPU;

重量级锁
将没有占有锁的线程全部放入阻塞队列。

CAS

Compare And Swap:乐观锁,先将值从内存空间中拷贝到工作空间中,当要修改时,先从内存中读取该值,如果与之前存的值相同,就修改,否则重新读取。

原理:通过调用Java原生包下的Unsafe类的CAS方法来实现,该方法被jvm编译为CAS汇编指令,是硬件层面的,其执行过程必是原子性的。

缺点:
1.底层使用的do while循环可能会时间过长;
2.只能保证单个共享变量的原子操作;
3.存在ABA问题(一个变量可能在过程中修改了多次,虽然前后结果一样)

ABA问题解决:调用AtomicStampReference类中的compareAndSet方法,该方法为变量设置了一个版本号,每次修改时版本号加一。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值