Java虚拟机-线程安全与锁优化

文章目录

目录

文章目录

前言

一、线程安全

二、高效并发-锁优化

总结


前言

主要介绍了Java虚拟机的线程安全与锁优化。


一、线程安全

  • 定义
    • 多线程访问一个共享资源时,代码本身封装了所有必要的正确性同步保障,调用者无需考虑多线程下的调用问题,不需要自己实现任何同步手段,都可以获得正确的结果,可以被称为绝对的线程安全
  • 分类
    • 不可变
      • final修饰的基本数据类型,final + private修饰对象中的成员变量和方法,所有该类型数据都只在常量池中存在一份且不可变,final和private还可以防止继承重写导致的局部变量引用暴露问题
      • 每次写操作都不会作用在原对象上,而是操作在一个新的复制值上,多线程写写、读写并发(读读会共享)不会导致共享同一个对象(类似JUC中的CopyOnWrite,但是其中写写也不能并发)
    • 绝对线程安全
      • 实现不论运行时环境如何,调用者都不需要任何额外的同步措施,就可以实现多线程安全并发共享访问同一个对象
    • 相对线程安全
      • 单次调用线程安全,组合连续调用时,调用端需要采取额外的同步手段(线程安全类的方法单独使用安全,组合使用不安全)
    • 线程兼容
      • 对象本身不安全,调用端采取同步手段后,可以实现在多线程情况下安全访问
    • 线程对立
      • 多线程情况下,无论调用端是否采用同步手段,都无法实现线程安全,应当避免使用
  • 实现
    • 互斥阻塞同步
      • synchronize、ReentrantLock(等待可中断、可实现公平锁、多个条件变量)、信号量Semaphore(一个共享资源被有限个线程共享访问)、ReentrantReadWriteLock
      • 悲观思想:一个线程持有锁后,其他线程不允许获取锁做任何操作
    • 非阻塞同步
      • 如何实现
        • CAS+volatile实现基于冲突检测的乐观锁,出现多线程竞争时,修改失败则反复重试直到修改成功
        • CAS { 第一个参数=待修改值的地址;第二个参数=待修改值原始值;第三个参数=待修改值修改后值 } 通过地址找到真实值与2号参数对比,相同修改为3号参数,否则一直循环重试,会返回原始值
      • 实现要求
        • 基于硬件指令集的发展,要求操作与冲突检测在硬件层面只需要一条处理器指令,具备原子性
      • 细节
        • Unsafe类
          • CAS基于Unsafe类,该类不提供给用户使用,用户使用CAS操作时,需要通过反射手段突破Unsafe类的访问权限
        • ABA问题
          • CAS操作无法感知到待修改变量中间状态的变化(A->B->A无法感知B的存在),引入AtomicStampedReference、AtomicMarkedReferense每次改变都改变标记
    • 无同步方案
      • 不涉及共享数据的方法代码天生线程安全
      • 分类
        • 可重入代码
          • 方法的返回结果是可以预测的,只要输入相同,一定会得到相同输出
          • 不涉及共享的数据(全局变量、堆中数据),不调用非可重入的方法
          • 方法可重入一定线程安全,线程安全不一定可重入
        • 线程本地存储
          • 共享数据的可见性范围限制在同一个线程之中
          • 通过java.lang.ThreadLocal实现某个变量被某个线程独享的本地存储功能

二、高效并发-锁优化

  • 自旋锁与自适应锁
    • 得不到锁时,不直接阻塞而是自旋重复请求锁一段时间,后升级为自适应调节自旋时间
    • 临界区代码块执行速度很快时,频繁阻塞导致的上下文切换会导致效率降低
  • 锁消除
    • 及时编译器会编译优化掉一些不存在共享数据竞争的锁,提高效率
  • 锁粗化
    • 一系列零碎操作都对一个对象重复上锁时,将上锁范围扩大到包含整个操作序列
  • 轻量级锁
    • 只在栈中记录Lock Record(与对象头中Mark Word交换位置),不为对象关联Monitor,出现多线程同时竞争锁时升级为重量级锁,为对象关联Monitor
    • 无竞争情况,用CAS消除同步使用的互斥量
  • 偏向锁
    • 在对象头Mark Word中记录第一次访问锁的线程ID,使得锁只能被该线程访问,出现别的线程访问锁(不是同时竞争)会升级为轻量级锁,出现同时竞争锁升级为重量级锁
    • 无竞争情况,消除同步操作(CAS也不使用)
    • 调用hashcode后,对象头空间不够,无法使用偏向锁
    • 优化
      • 批量重偏向
        • 偏向锁撤销升级为轻量级锁太多次后,后面需要撤销的偏向锁,可以直接重新偏向第二次访问锁的线程
      • 偏向锁撤销
        • 偏向锁撤销升级、重偏向太多次(太多线程想访问锁),撤销偏向锁,直接上轻量级锁,出现同时竞争升级为重量级锁

总结

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值