Java锁系列1/3--常用锁的分类

说到线程安全,经常会用到锁。了解锁有哪些,锁又是如何设计的,对在业务中选择合适的锁很重要。

(一)锁的分类概述

在这里插入图片描述

(二)锁的分类详解

1.可重入锁 、不可重入锁

类型概念(同一个线程角度分析)类型模型
可重入锁可以重入上锁的代码段方法调用时,次都可访问另一个方法(例如:递归)
不可重入锁不可以重入上锁后的代码段独立的访问每一个方法,加锁 - 释放

2.共享锁、排他锁

类型概念示例
共享锁可被多个线程所持有ReadWriteLock的读锁
排他锁一次只能被一个线程所持有ReadWriteLock的写锁

3.公平锁、非公平锁

类型概念(多个线程角度分析)特点
公平锁按照申请锁的顺序来获取锁公平
非公平锁获取锁的顺序并不是按照申请锁的顺序吞吐量比公平锁大,但可能造成饥饿现象

4.偏向锁、轻量级锁、重量级锁(锁的状态)

  • Java 5通过引入锁升级的机制来实现高效Synchronized,通过对象监视器在对象头中的字段来表明。
类型概念特点
偏向锁一段同步代码一直被一个线程所访问,那么该线程会自动获取锁降低获取锁的代价
轻量级锁当锁是偏向锁的时候,被另一个线程所访问,偏向锁就会升级为轻量级锁,其他线程会通过自旋的形式尝试获取锁不会阻塞,提高性能
重量级锁锁为轻量级锁的时候,另一个线程虽然是自旋,但自旋不会一直持续下去,当自旋一定次数的时候,还没有获取到锁,就会进入阻塞,该锁膨胀为重量级锁重量级锁会让他申请的线程进入阻塞,性能降低

5.乐观锁、悲观锁(看待并发同步的角度)

类型概念场景
乐观锁每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。多读的,提高吞吐量
悲观锁对于同一个数据的并发操作,一定会发生修改的(实际上可能未修改)。因此对于同一份数据的并发操作,采取加锁的形式。加锁失败,说明该记录正在被修改,当前查询可能要等待或者抛出异常(开发者决定)

6.自旋锁

类型概念特点
自旋锁概念尝试获取锁的线程不会立即阻塞,而是采用循环的方式去尝试获取锁减少线程上下文切换的消耗;但是循环会消耗CPU

(三)锁的设计

锁的设计用锁的粒度很好解释,锁的粒度涉及到临界区。临界区大,我们保护的范围更大,但是会影响效率,而临界区小了,可能又会导致不安全。
如何不知道如何选择,可以先保证安全,再进行优化。
临界区:我们居住的房子,门上都会有锁,而我们锁住的也是这个屋子的安全,而这个屋子就是临界区。

总结

了解了锁的分类,算是对锁有个基本认识了。要想更深入的了解锁,还需要了解锁底层原理,而常用锁底层实现都是 AQS实现的,下一篇我们就来聊聊【Java锁系列2/3–分析AQS源码】

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值