jmm与并发

本文深入探讨了Java内存模型(JMM)的核心概念,包括主内存与工作内存的区别,volatile变量的特性和实现机制,以及synchronized关键字如何确保原子性、可见性和有序性。通过解析JMM的内存交互操作和先行发生原则,帮助读者理解并发编程中的关键问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JMM

  1. 主内存和工作内存
    1. 主内存
      1. 包括:实例字段、静态字段、和构成数组对象的元素;但不包括局部变量和方法参数,因为他们是线程私有的
      2. 所有变量都存储在主内存
    2. 工作内存是线程使用到的变量的主内存的副本,线程对变量的操作必须在工作内存中进行
  2. 内存交互操作
    1. lock
    2. unlock
    3. read
    4. load
    5. use
    6. assign
    7. store
    8. write
  3. 操作规则:

volatile ——jvm P362-jmm

  1. 变量定义为volatile之后具备两种特性 :
    1. 保证变量对所有线程的可见性 不保证原子性
    2. 禁止指令重排
  2. 实现:
    1. 可见性 :在对volatile变量赋值之后,会多执行一个lock语句,使得本cpu的cache写入内存,写入操作会使别的cpu无效化其cache,需要使用该变量时,需要重写从主存读取,进而实现可见性
    2. 禁止指令重排 :lock使本cpu的cache写入内存,需要保证lock前的操作执行完毕(因为指令重排不能影响程序运行结果),所以可以保证lock前的操作发生在lock后的操作前。
  3. volatile 规则:
    1. 使用变量前,需要从主存刷新,保证可以看到其他线程的修改
    2. 修改变量后,立即写回主存,保证可以让其他线程看到
    3. 禁止指令重排 (原文《深入理解jvm》P372 我看不懂)
  4. 针对64位基本类型——long, double,允许jvm不保证其load, store, read, write操作的原子性。

原子性,可见性,有序性

——jmm是围绕这并发过程中如何处理这三个特性建立起来的,以下是哪些操作可以实现三个特性

  1. 原子性
    1. 定义
    2. 实现:jmm层次:lock,unlock;字节码指令monitorenter,monitorexit;关键字synchronized
  2. 可见性
    1. 定义
    2. 实现:volatile,synchronized,final
      1. synchronized 使用lock和unlock实现 unlock之前须将变量写回内存
      2. final 假如this引用未逃逸(this引用逃逸可能使其他线程访问到初始化了一半的对象),final因为不可变所以工作内存中的副本和主存相同,可以保证可见性
  3. 有序性
    1. 定义
    2. 实现
      1. volatile禁止指令重排
      2. synchronized 变量同时只允许一条线程lock,而单一线程的所有操作尽管会重排序,但不影响结果,可以认为有序。

先行发生原则

  1. 程序次序规则:一个线程内,按按照代码顺序执行
  2. 管程锁定规则:同一个锁的unlock先行与后面的lock
  3. volatile变量规则:对volatile变量的写操作先行发生与后面的读操作
  4. 线程启动规则:thread的start方法先行发生于此线程的每一个动作
  5. 线程终止规则:线程的所有操作都先行发生于对此线程的终止检测
  6. 线程中断规则:对线程的interrupt操作先行发生于检测到线程中断的发生
  7. 对象终结规则:对象的初始化完成先行于它的finalize的开始
  8. 传递性:A先于B,B先于C ,则A先于C
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值