一、公平锁和非公平锁
- 公平锁:指多个线程按照申请锁的顺序来获取锁
- 非公平锁:没有顺序完全随机,所以会造成优先级反转
举例:
synchronized就是非公平锁
ReentrantLock(使用CAS和AQS实现)通过构造参数可以决定是非公平锁还是公平锁,默认构造是非公平锁,非公平锁的吞吐量性能比公平锁大好。
二、可重入锁和不可重入锁
- 可重入锁:又名递归锁,指同一线程在外层方法获取锁的时候进入内层方法会自动获取锁
- 不可重入锁:即当前线程执行某个方法已经获取了该锁,那么在方法中尝试再次获取锁时,就会获取不到被阻塞。
举例:
synchronized和ReentrantLock都是可重入锁,可重入锁可以在一定程度上避免死锁。
不可重入锁目前没遇到过。
三、独享锁和共享锁
- 独享锁:指该锁一次只能被一个线程持有
- 共享锁:指该锁可以被多个线程所持有
举例:
synchronized和ReentrantLock都是独享锁
ReadWriteLock的读锁是共享锁,写锁是独占锁(ReadWriteLock是一个接口,实现类有ReetrantReadWriteLock)
四、乐观锁和悲观锁
这个分类不是具体锁的分类,而是看待并发同步的角度。
- 乐观锁:认为对于同一数据的并发操作是不会发生修改的,在更新数据的时候会采用不断的尝试更新,乐观锁认为不加锁的并发操作是没事的。
- 悲观锁:认为对于同一个数据的并发操作一定是会发生修改的(哪怕实质没修改也认为会修改),因此对于同一个数据的并发操作,悲观锁采取加锁的形式,因为悲观认为不加锁的操作一定有问题。
乐观锁适合 读操作 非常多的场景,不加锁会带来大量的性能提升,乐观锁就是基于CAS的无锁编程。如java的原子类就是通过CAS自旋实现的。
悲观锁适合 写操作 非常多的场景。
五、分段锁
实际上一种锁的策略,不是具体的锁。
- 分段锁的设计是为了细化锁的粒度。
举例:
jdk1.7的ConcurrentHashMap的实现就是通过分段锁的形式来实现高效并发操作。
当要put元素时并不是对整个hashmap加锁,而是先通过hashcode知道它要放在哪个分段,然后对分段进行加锁,所以多线程put元素时只要放在的不是同一个分段就做到了真正的并行插入,但是统计size时就需要获取所有的分段锁才能统计。
六、偏向锁、轻量级锁、重量级锁
这几种状态都不是java语言中的锁,而是jvm为了提高锁的获取与释放而做的优化(使用synchronized时)
- 偏向锁:
指一段同步代码一直被一个线程所访问,那么该线程就会自动获取锁。降低获取锁的代价。
- 轻量级锁:
指当锁是偏向锁的时候,被另一个线程所访问,偏向锁就会升级为轻量级锁,其他线程会通过自旋的形式尝试获取锁,不会阻塞,提高性能。
- 重量级锁:
指当锁为轻量级锁的时候,另一个线程虽然自旋,但自旋不会一直持续下去,当自旋一定次数的时候,还没有获取锁,就会进入阻塞,该锁膨胀为重量级锁。重量级锁会让其他申请的线程进入阻塞,性能降低。
其实一共有四种状态,分别是无锁状态、偏向锁状态、轻量级锁状态、重量级锁状态。
锁的状态是通过对象监视器在对象头中的字段来声明的。
这四种状态会随着竞争的情况逐渐升级,而且是不可逆的过程,即不可降级。
备注:
锁的状态在对象头中怎么标记声明,这个有需要的时候再进行补充,暂时不深究。
七、自旋锁
- 自旋锁的线程一直是RUNNABLE状态的,一直在那循环检测锁标志位,但是全程消耗cpu。起始开销虽然低于互斥锁,但随着持锁时间加锁开销是线性增长。
其实自旋锁的概念是相对于互斥锁的概念,互斥锁线程会进入WAITING状态和RUNNABLE状态的切换,涉及上下文切换、cpu抢占等开销。
八、可中断锁
- 就是可以中断的锁
synchronized是不可中断的,Lock是可中断的,这里的中断建立在阻塞等待中断,运行中是无法中断的。
更多java基础总结(适合于java基础学习、java面试常规题):
总结篇(9)---字符串及基本类 (1)字符串及基本类之基本数据类型
总结篇(10)---字符串及基本类 (2)字符串及基本类之java中公共方法及操作
总结篇(12)---字符串及基本类 (4)Integer对象
总结篇(14)---JVM(java虚拟机) (1)JVM虚拟机概括
总结篇(15)---JVM(java虚拟机) (2)类加载器
总结篇(16)---JVM(java虚拟机) (3)运行时数据区
总结篇(17)---JVM(java虚拟机) (4)垃圾回收
总结篇(18)---JVM(java虚拟机) (5)垃圾回收算法
总结篇(19)---JVM(java虚拟机) (6)JVM调优
总结篇(24)---Java线程及其相关(2)多线程及其问题
总结篇(25)---Java线程及其相关(3)线程池及其问题
总结篇(26)---Java线程及其相关(4)ThreadLocal
总结篇(27)---Java并发及锁(1)Synchronized
总结篇(31)---JUC工具类(1)CountDownLatch
本文详细介绍了Java中的多种锁机制,包括公平锁与非公平锁、可重入锁与不可重入锁、独享锁与共享锁等,并探讨了乐观锁与悲观锁的不同应用场景。此外还解释了分段锁、自旋锁、可中断锁的概念及其适用场景。
572

被折叠的 条评论
为什么被折叠?



