JAVA并发编程-一文看懂全部锁机制

简介: 曾几何时,面试官问:java都有哪些锁?小白,一脸无辜:用过的有synchronized,其他不清楚。面试官:回去等通知!今天我们庖丁解牛说说,各种锁有什么区别、什么场景可以用,通俗直白的分析,让小白再也不怕面试官八股文拷打。

曾几何时,面试官问:java都有哪些锁?小白,一脸无辜:用过的有synchronized,其他不清楚。面试官:回去等通知!

    今天我们庖丁解牛说说,各种锁有什么区别、什么场景可以用,通俗直白的分析,让小白再也不怕面试官八股文拷打。

    之前的文章说过《JAVA并发编程synchronized全能王的原理》、以及《JAVA并发编程JUC包之CAS原理》,synchronized、CAS都是常见的锁。那么锁的类型是如何划分的呢?

一、按特性划分

1.1 悲观锁和乐观锁

按线程访问共享资源时,要不要锁住同步资源来定义。比如synchronized就是悲观锁,数据库的行锁、表锁都是悲观锁。

CAS就是乐观锁,数据库版本号机制也是乐观锁。

    悲观锁的应用场景:大量更新修改操作,使用悲观锁,可以保证数据强一致性。

    乐观锁的应用场景:读多写少的场景,提高吞吐量。

1.2 可重入锁和不可重入锁

一个线程,是否可以重复获取同一把锁。比如synchronized、ReentrantLock是可重入锁,可以重复加锁。可重入锁在加锁N次后,解锁就需要进行N次解锁。效率较低,但是好处是可以避免死锁,因为在方法内部递归,如果使用普通锁,可能会出现死锁。而可重入锁支持线程重复进入同一个代码块。

1.3 公平锁和非公平锁

多线程竞争同一个锁时,是否需要排队,以及是否可以插队。

    公平锁,就是多个线程按顺序申请锁。比如new ReentrantLock(true),就是公平锁。

    非公平锁,就是多个线程获取锁不是按申请顺序获得,可以插队。比如new ReentrantLock(false), synchronized。

非公平锁的缺点,就是可能导致线程饥饿现象,某个线程或多个线程由于优先级较低,长期被其他优先级较高的线程插队抢夺锁资源,导致无法获得CPU执行。

1.4 独享锁和共享锁

    独享锁、共享锁,也叫排它锁和非排它锁。

依据是:多个线程能否同时共享同一个锁。

   独享锁=排它锁,比如synchronized、ReentrantLock,ReentrantReadWriteLock的write写锁,都是独享锁。

   共享锁=非排它锁,比如ReentrantReadWriteLock的readLock读锁就是共享锁。

   也有人说,互斥锁,其实也是独享锁。有人说读写锁,对应的就是ReentrantReadWriteLock。

二、按上锁方式划分

2.1 隐式锁和显式锁

    按是否显式的执行加锁和解锁过程。比如synchronized,我们使用它后,不需要显式的解锁。而JUC包的ReentrantLock就需要显式的lock(),unlock().

三、其他类型锁

自旋锁,锁获取失败后, 线程不会阻塞,而是循环尝试获取锁直至成功。比如CAS、轻量级锁都是自旋锁。

分段锁,将锁的粒度划分更细,当一个线程对一段数据进行加锁访问时,其他段的数据可以被其他线程同时访问。比如concurrentHashMap,就是使用锁分段技术。

四、synchronized的锁状态

无锁、偏向锁、轻量级锁、重量级锁四种状态。其中JDK1.6新增了偏向锁和轻量级锁。这四种状态是随着多线程竞争,逐级升级的状态,不可逆不可降级。是JVM特定给synchronized提升效率而做的优化。

   偏向锁:就是只有一个线程访问共享资源时,不会加锁,只是记录当前持有锁资源线程的锁类型,然后该线程每次执行这部分共享资源,都只是判断是否持有锁,以及当前锁类型。

   轻量级锁:在偏向锁的基础上,如果当前有两个线程在交替竞争锁,这时候将锁状态膨胀为【轻量级锁】。同时竞争失败的线程,不阻塞,用CAS自旋循环等待获取锁。

   重量级锁:轻量级锁,自旋一定次数后,膨胀为重量级锁,竞争失败的线程直接进入阻塞状态,等持有锁的线程释放锁后再唤醒。

相关文章
|
4月前
|
Java
如何在Java中进行多线程编程
Java多线程编程常用方式包括:继承Thread类、实现Runnable接口、Callable接口(可返回结果)及使用线程池。推荐线程池以提升性能,避免频繁创建线程。结合同步与通信机制,可有效管理并发任务。
213 6
|
4月前
|
IDE Java 编译器
java编程最基础学习
Java入门需掌握:环境搭建、基础语法、面向对象、数组集合与异常处理。通过实践编写简单程序,逐步深入学习,打牢编程基础。
274 1
|
5月前
|
SQL Java 数据库
2025 年 Java 从零基础小白到编程高手的详细学习路线攻略
2025年Java学习路线涵盖基础语法、面向对象、数据库、JavaWeb、Spring全家桶、分布式、云原生与高并发技术,结合实战项目与源码分析,助力零基础学员系统掌握Java开发技能,从入门到精通,全面提升竞争力,顺利进阶编程高手。
972 1
|
4月前
|
安全 前端开发 Java
从反射到方法句柄:深入探索Java动态编程的终极解决方案
从反射到方法句柄,Java 动态编程不断演进。方法句柄以强类型、低开销、易优化的特性,解决反射性能差、类型弱、安全性低等问题,结合 `invokedynamic` 成为支撑 Lambda 与动态语言的终极方案。
204 0
|
5月前
|
Java 开发者
Java并发编程:CountDownLatch实战解析
Java并发编程:CountDownLatch实战解析
506 100
|
安全 Java 程序员
Java并发编程中的锁机制与优化策略
【6月更文挑战第17天】在Java并发编程的世界中,锁是维护数据一致性和线程安全的关键。本文将深入探讨Java中的锁机制,包括内置锁、显式锁以及读写锁的原理和使用场景。我们将通过实际案例分析锁的优化策略,如减少锁粒度、使用并发容器以及避免死锁的技巧,旨在帮助开发者提升多线程程序的性能和可靠性。
|
安全 Java 编译器
Java并发编程中的锁优化策略
【5月更文挑战第30天】 在多线程环境下,确保数据的一致性和程序的正确性是至关重要的。Java提供了多种锁机制来管理并发,但不当使用可能导致性能瓶颈或死锁。本文将深入探讨Java中锁的优化策略,包括锁粗化、锁消除、锁降级以及读写锁的使用,以提升并发程序的性能和响应能力。通过实例分析,我们将了解如何在不同场景下选择和应用这些策略,从而在保证线程安全的同时,最小化锁带来的开销。
|
安全 Java
Java并发编程中的锁优化策略
【5月更文挑战第25天】在Java并发编程中,锁是实现线程同步的关键。然而,锁的使用可能导致性能下降,尤其是在高并发场景下。为了提高程序的执行效率,本文将探讨几种常用的锁优化策略,包括自旋锁、适应性锁和锁粗化等技术。通过这些优化策略,我们可以在保证线程安全的同时,提高程序的运行效率。
93 3
|
安全 Java 开发者
Java并发编程中的锁优化策略
【5月更文挑战第30天】 在Java并发编程领域,锁机制是实现线程同步的关键手段之一。随着JDK版本的发展,Java虚拟机(JVM)为提高性能和降低延迟,引入了多种锁优化技术。本文将深入探讨Java锁的优化策略,包括偏向锁、轻量级锁以及自旋锁等,旨在帮助开发者更好地理解和应用这些高级特性以提升应用程序的性能。
|
缓存 Java 编译器
Java并发编程中的锁优化策略
【5月更文挑战第27天】在Java多线程开发中,锁是一种常用的同步机制,用于保证共享资源的访问顺序和一致性。然而,不当的锁使用会导致性能瓶颈甚至死锁。本文将探讨Java并发编程中的锁优化策略,包括锁粗化、锁消除、锁细化以及读写锁的使用,旨在帮助开发者提高程序的性能和可靠性。