当前位置: 首页 > news >正文

并发编程:各种锁机制、锁区别、并发工具类深刻总结

 博主总结

  • 1、各种锁全面快速了解

    • 悲观锁(排他锁、互斥锁),上下文切换频繁。适合并发量高、对读写资源竞争高的场景
    • 乐观锁(自旋锁,循环实现CAS机制),读多写少且竞争小的。轻量,避免锁竞争。因此在读取数据时不加锁,而是在更新数据时通过CAS机制来验证数据是否被其他线程修改过。ABA问题是在使用CAS时可能出现的一种并发问题。在多线程环境下,如果一个变量的值先被线程A修改为B,然后又被线程B修改回A,那么在使用CAS进行比较和交换操作时,尽管变量的当前值与预期值相同(都是A),但实际上这个变量的值已经被修改过,这就是ABA问题。
    • 公平锁(先来后到)、非公平锁(本线程优先获取锁, synchornized)
    • 排他锁和共享锁,可以看作写锁(会造成线程安全问题)和读锁(不会造成线程安全问题,会共享起来提升读的性能,可结合Volatile保证可见性)
    • 可重入锁(递归锁),可重入锁其实就是同一个线程持有的锁,synchronized和ReentranLock具有可重入锁特性,可重复持有的锁

    • 锁升级:无锁 -> 偏向锁(可看作可重入锁) -> 轻量级锁 (可看作乐观锁)-> 重量级锁(悲观锁(自旋锁),涉及到从应用态切换到内核态),它们是synchornized底层所升级的四种状态,synchornized随着并发量的增加锁的重量就会增加,锁越重性能越低但就越安全。
  • 2、悲观锁和乐观锁详解

    • 悲观锁与乐观锁是什么?
      • 悲观锁:共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程。synchronized和ReentrantLock等独占锁就是悲观锁思想的实现。
      • 乐观锁:无需加锁也无需等待,只是在提交修改的时候去验证对应的资源(也就是数据)是否被其它线程修改了(具体方法可以使用版本号机制或 CAS 算法)。在 Java 中java.util.concurrent.atomic包下面的原子变量类(比如AtomicInteger、LongAdder)就是使用了乐观锁的一种实现方式 CAS 实现的。
        • LongAdder:它在内部维护了多个计数器(通常使用数组),每个线程可以独立地对自己的计数器进行更新,从而减少竞态条件。只有在需要计算总和时,这些计数器的值才会被汇总。因此,它在高并发场景下能够提供更好的性能。
    • 悲观锁和乐观锁如何选用?
      • 悲观锁通常多用于写比较多的情况(多写场景,竞争激烈),这样可以避免频繁失败和重试影响性能,悲观锁的开销是固定的。不过,如果乐观锁解决了频繁失败和重试这个问题的话(比如LongAdder),也是可以考虑使用乐观锁的,要视实际情况而定。
      • 乐观锁通常多用于写比较少的情况(多读场景,竞争较少),这样可以避免频繁加锁影响性能。不过,乐观锁主要针对的对象是单个共享变量(参考java.util.concurrent.atomic包下面的原子变量类)。
    • 乐观锁的实现(CAS和版本号法,CAS相对使用较多)
      • CAS,下面详解吧!
      • 版本号法:一般是在数据表中加上一个数据版本号 version 字段,表示数据被修改的次数。当数据被修改时,version 值会加一。当线程 A 要更新数据值时,在读取数据的同时也会读取 version 值,在提交更新时,若刚才读取到的 version 值为当前数据库中的 version 值相等时才更新,否则重试更新操作,直到更新成功。
  • 3、synchronized和volatile区别?

    • synchronized 关键字和 volatile 关键字是两个互补的存在,而不是对立的存在!
    • volatile 关键字是线程同步的轻量级实现,所以 volatile性能肯定比synchronized关键字要好 。但是 volatile 关键字只能用于变量而 synchronized 关键字可以修饰方法以及代码块 。
    • volatile 关键字能保证数据的可见性,但不能保证数据的原子性。synchronized 关键字两者都能保证。
    • volatile关键字主要用于解决变量在多个线程之间的可见性,而 synchronized 关键字解决的是多个线程之间访问资源的同步性。
  • 4、synchronized和reentrantLock区别?

    • 二者都是可重入锁。
    • synchronized依赖于JVM,而RentrantLock依赖于JDK的API实现。
    • ReentrantLock相较于sync提供很多功能增强。
      • 等待可中断 : ReentrantLock提供了一种能够中断等待锁的线程的机制,通过 lock.lockInterruptibly() 来实现这个机制。也就是说当前线程在等待获取锁的过程中,如果其他线程中断当前线程「 interrupt() 」,当前线程就会抛出 InterruptedException 异常,可以捕捉该异常进行相应处理。
      • 可实现公平锁 : ReentrantLock可以指定是公平锁还是非公平锁。而synchronized只能是非公平锁。所谓的公平锁就是先等待的线程先获得锁。ReentrantLock默认情况是非公平的,可以通过 ReentrantLock类的ReentrantLock(boolean fair)构造方法来指定是否是公平的。
      • 可实现选择性通知(锁可以绑定多个条件): synchronized关键字与wait()和notify()/notifyAll()方法相结合可以实现等待/通知机制。ReentrantLock类当然也可以实现,但是需要借助于Condition接口与newCondition()方法。
      • 支持超时 :ReentrantLock 提供了 tryLock(timeout) 的方法,可以指定等待获取锁的最长等待时间,如果超过了等待时间,就会获取锁失败,不会一直等待。
  • 5、公平锁和非公平锁区别?

    • 公平锁 : 锁被释放之后,先申请的线程先得到锁。性能较差一些,因为公平锁为了保证时间上的绝对顺序,上下文切换更频繁。
    • 非公平锁:锁被释放之后,后申请的线程可能会先获取到锁,是随机或者按照其他优先级排序的。性能更好,但可能会导致某些线程永远无法获取到锁。
  • 6、可中断锁和不可中断锁区别?

    • 可中断锁:获取锁的过程中可以被中断,不需要一直等到获取锁之后 才能进行其他逻辑处理。ReentrantLock 就属于是可中断锁。
    • 不可中断锁:一旦线程申请了锁,就只能等到拿到锁以后才能进行其他的逻辑处理。 synchronized 就属于是不可中断锁。
  • 7、共享锁和独占锁区别?

    • 共享锁:一把锁可以被多个线程同时获得。
    • 独占锁:一把锁只能被一个线程获得。
  • 8、并发工具类

    • CountDownLatch 是 JUC 中的一个同步工具类,用于协调多个线程之间的同步,确保主线程在多个子线程完成任务后继续执行。
    • CyclicBarrier 的字面意思是可循环使用的屏障,用于多个线程相互等待,直到所有线程都到达屏障后再同时执行。
    • Semaphore——信号量,用于控制同时访问某个资源的线程数量,类似限流器,确保最多只有指定数量的线程能够访问某个资源,超过的必须等待。

    • Exchanger——交换者,用于在两个线程之间进行数据交换。
    • CyclicBarrier和CountDownLatch区别?

http://www.xdnf.cn/news/589663.html

相关文章:

  • 关于标准盒模型和怪异盒模型
  • python正方形面积 2024年信息素养大赛复赛/决赛真题 小学组/初中组 python编程挑战赛 真题详细解析
  • 数据分析师如何用OKR驱动业务增长
  • 钉钉通讯录与金蝶云星空无缝集成的技术实现方法
  • AI时代的操作系统:VAST如何重塑基础设施新标准?
  • SenseGlove Nova2 力反馈数据手套:助力外科手术训练的精准触觉模拟
  • 海外 APP 开发的全方位指南:从技术架构到市场进入的综合策略
  • 2023CCPC东北四省赛题解
  • 关于 Burp Suite 详解
  • 一键安装docker
  • Java 内存模型中的读、写屏障
  • 文化基因算法(Memetic Algorithm)详解:原理、实现与应用
  • 服务器磁盘按阵列划分为哪几类
  • MySQL8.0新特性:新特性深度应用解析
  • 【深度学习新浪潮】2025年谷歌I/O开发者大会keynote观察
  • 场景化应用实战系列五:互联网舆情检测
  • 技术分享 | MySQL大事务导致数据库卡顿
  • Java—— IO流 第三期
  • 使用 OpenCV 构建稳定的多面镜片墙效果(镜面反射 + Delaunay 分块)
  • MinerU教程第二弹丨MinerU 本地部署保姆级“喂饭”教程
  • Oracle 物理存储与逻辑管理
  • 偏微分方程数值方法指南及AI推理
  • 深入理解Diffusers: 从基础到Stable Diffusion
  • (07)数字化转型之产品材料管理:从基础数据到BOM的全生命周期管理
  • Basic concepts for seismic source - Finite fault model
  • 【 开源:跨平台网络数据传输的万能工具libcurl】
  • DOM API-JS通过文档对象树操作Doc和CSS
  • 【Linux 学习计划】-- makefile
  • shell脚本总结5
  • 当AI遇上科研:北大“科学导航”重塑学术探索全流程