并发编程_jmm部分

这篇具有很好参考价值的文章主要介绍了并发编程_jmm部分。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. JMM 理解

前提:并发编程有3大问题,可见性、有序性、原子性。
导致可见性的原因是缓存,有序性的原因是 编译器优化。解决方法就是直接禁用缓存和编译器优化,导致程序性能堪忧。
因此合理的方案就是按需禁用缓存和编译器优化。

JMM定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存(main memory)中,每个线程都有一个私有的本地内存(local memory),本地内存中存储了该线程以读/写共享变量的副本。

所以: java 内存模型针对在多线程环境下,可见性 有序性制定了一些规范,在jvm 层面 提供按需禁用缓存和编译优化的方法。具体就是使用synchronized,volatile,final三个关键字和Happens-before 规则。 解决并发编程中 的代码的有序性和可见性。

long double 32位原子性问题。

并发编程_jmm部分,# 并发编程 jvm,java
如果需要保证 long 和 double 在 32 位系统中原子性,需要用 volatile 修饰

load load 两个连续的读不要重排序 防止读跑上去

防止 B 的 Load 重排到 A 的 Load 之前

if(A) {
    LoadLoad
    return B
}

read(A)
LoadLoad
read(B)
  • 意义:A == true 时,再去获取 B,否则可能会由于重排导致 B 的值相对于 A 是过期的
    并发编程_jmm部分,# 并发编程 jvm,java

loadstore 防止连续 读写 防止写跑上去。

并发编程_jmm部分,# 并发编程 jvm,java

Acquire 第一个是load,防止后续的 读、写 不要重排序

同一线程内,读 操作之后的的读写,上不去,同时第一个load能读到主存中的最新值。
并发编程_jmm部分,# 并发编程 jvm,java

store store 连续的写 防止写跑下来

  • 防止 A 的 Store 被重排到 B 的 Store 之后
A = x
StoreStore
B = true
  • 意义:在 B 修改为 true 之前,其它线程别想看到 A 的修改
    • 有点类似于 sql 中更新后,commit 之前,其它事务不能看到这些更新(B 的赋值会触发 commit 并撤除屏障)
      并发编程_jmm部分,# 并发编程 jvm,java

release 防止读和写 跑下来。 ss ls

同一线程内,写操作之前的 , 读写下不来,后面的store 都能将改动的 都写入主存。
store store
load sore
防止上面的 读操作 写操作,被重排序到 写操作下面
并发编程_jmm部分,# 并发编程 jvm,java

store load ** 发生在线程切换时有效。 保证可见性。

sotre load 屏障 在线程切换时,保证可见性。

意义:屏障前的改动都同步到主存,屏障后的 Load 获取主存最新数据

  • 防止屏障前所有的写操作,被重排序到屏障后的任何的读操作,可以认为此 store -> load 是连续的
  • 有点类似于 git 中先 commit,再远程 poll,而且这个动作是原子的
    并发编程_jmm部分,# 并发编程 jvm,java

2.volatile 本质

写变量时 加 loadstore store store 屏障 和 store load 屏障

红色 蓝色是两个线程。
并发编程_jmm部分,# 并发编程 jvm,java

读取变量时 load load ,load store

在变量加入load load load store 屏障
并发编程_jmm部分,# 并发编程 jvm,java

1. 保证单一变量赋值的原子性

32 位操作系统,long double

2. 保证变量的有序性

线程内通过内存屏障保证有序,线程切换按照happen-before 有序。

partial ordering

total ordering

3. 可见性

线程切换时 ,发生了写->读,则变量可见,顺便影响普通变量可见性。
在volatile 变量 加入store load 屏障。
红色线程的写入同步到主存,然后让蓝色线程的读取,取主存中读取最新值。
并发编程_jmm部分,# 并发编程 jvm,java

3. Synchronization order

线程内部的一个顺序

4.happen-before 原则

在线程切换时,代码的顺序 和可见性。

表达的是,前一个线程的操作的结果 对后续线程的操作是可见的。

线程启动 和运行边界

线程1 启动线程2前对共享变量进行修改,在线程2运行时,读取共享变量一定能看到修改。
并发编程_jmm部分,# 并发编程 jvm,java

线程的结束 和join 的边界。

线程1 结束前,对共享变量的修改。t2线程等待t1线程的解释 join,t2也能读取到共享变量的读取。

线程的打断 和得知线程的打断。

interrupt
t1线程修改共享变量,t1线程对t2线程打断,t2线程得知打断,能够读取到共享变量的改变。
并发编程_jmm部分,# 并发编程 jvm,java

unlock 和lock 边界。

t1线程解锁前对共享变量的修改,t2线程加锁后,能够读取到共享变量的修改。

volatile 对变量的写 和volatile 的读 的边界

传递性

如果a hb b,
b hb c,
那么有a hb c

5. cas 原理

使用乐观锁机制,保证变量读写的原子性。
volatile+ cas 实现原子 可见 有序
volatile 搭配cas 保证 共享变量的可见性。
线程数小于cpu 核心数,乐观锁性能高。

aqs 的state 使用volatile

cas + volatile 保证 state 的最新值 和 互斥。

concurrenthashmap 懒惰初始化

有一个sizectl 属性,volatile 修饰,保证可见性。
在第一次 put 时,检查sizectl,使用cas 把 0 改成 -1, (-1,hash表正在被初始化),
其他线程来 初始化 cas 失败,不会重复创建了。

6. synchronized

有序性

并发编程_jmm部分,# 并发编程 jvm,java
在monitor enter 和 monitor exit 加了相应的屏障,
保证了 同步代码块 内部的代码,共享变量的读写, 不会重排序到同步代码块的外面。
强调 :
但是 在同步代码块内部还是会存在重排序的。

7 反射

反射可见 对象自己的 类名、接口、父类、成员变量、方法。
类加载 收集 类的信息,记录在instance klass中

反射是直接获取加载了方法区的类模板,所以可以拿到整个类的所有东西,看似是打破了封装特性,但实际上反射的真正作用是为了解偶以及实现动态性
并发编程_jmm部分,# 并发编程 jvm,java

8 cas

CAS(Compare and Swap)是一种并发控制机制,用于解决多线程环境下的原子性操作问题。它主要包含以下步骤:

比较:首先,CAS操作会比较某个内存位置的当前值与预期值是否相等。

交换如果当前值与预期值相等CAS操作会将新值写入该内存位置。否则,表示其他线程已经修改了该内存位置的值,CAS操作失败。

返回结果:CAS操作返回一个标识,指示操作是否成功。

CAS操作是原子的,即在执行过程中不会被其他线程中断,并且能够确保操作的原子性。因此,CAS通常用于实现线程同步、无锁算法以及乐观锁等。

在实现上,CAS依赖底层硬件提供的原子指令,如x86处理器上的CMPXCHG指令。通过这些原子指令,CAS可以在一个操作中同时进行比较和交换操作,避免了传统锁机制所需的上下文切换和线程阻塞的开销。

需要注意的是,尽管CAS操作可以避免锁带来的开销,但它并不能解决所有并发问题。在高并发场景下,由于CAS的自旋操作可能导致大量的CPU资源消耗,因此需要根据具体情况权衡使用。此外,CAS操作在并发度较高、竞争激烈的情况下可能会引发ABA问题,需要额外的措施进行处理(如使用版本号或标记位)来确保数据的一致性。
#9 synchronzied
锁升级过程
并发编程_jmm部分,# 并发编程 jvm,java文章来源地址https://www.toymoban.com/news/detail-534366.html

到了这里,关于并发编程_jmm部分的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 区分什么是Java内存模型(JMM)和 JVM运行时数据区

    Java的内存区域和内存模型是不一样的东西,内存区域是指 JVM 运行时将数据分区域存储,强调对内存空间的划分 。 而内存模型(Java Memory Model,简称 JMM )是 定义了线程和主内存之间的抽象关系,即 JMM 定义了 JVM 在计算机内存(RAM)中的工作方式 ,如果我们要想深入了解Java并

    2024年02月11日
    浏览(51)
  • final IN JVM AND JMM

    In JMM (Java Memory Model), the final keyword is used to ensure visibility and immutability in a multi-threaded environment. In Java, the final keyword can be used to modify variables, methods, and classes, as follows: Modifying variables: A variable that is marked as final is immutable, meaning its value cannot be changed after initialization. In a multi-th

    2024年02月09日
    浏览(32)
  • Java 并发之《深入理解 JVM》关于 volatile 累加示例的思考

    在周志明老师的 《深入理解 JVM》一书中关于 volatile 线程安全性有一个示例代码(代码有些许改动,语义一样): 老师的目的是为了说明在多线程环境下 volatile 只能保证可见性而不是线程安全的。但是当在我的 IDEA 下运行时,发现程序是没有输出结果且始终是

    2024年01月20日
    浏览(53)
  • java语法(二)线程并发、Juit单元测试、反射机制、注解、动态代理、XML解析、JVM

    正则表达式验证网站 1、 ? :表示前边这个字符可以出现0次或者1次。例如下边 /used? 既可以匹配 use 也可以匹配 used 。 2、 * :匹配0个或者多个字符, * 号代表前边这个字符可以出现0次或者多次。例如 /ab*c 可以匹配 ac、abc、abbbbc 3、 + :与 * 号不同的是, + 需要前面这个字符

    2024年02月06日
    浏览(53)
  • Java并发编程:Semaphore

    信号量可以控制线程的并发数量 通常用于那些资源有明确访问数量限制的场景,常用于限流 。 使用 Semaphore 先调用 acquire() 获取,然后通过 try ... finally 保证在 finally 中释放。 Semaphore常用方法说明 acquire() 获取一个令牌,在获取到令牌、或者被其他线程调用中断之前线程一直

    2024年02月12日
    浏览(41)
  • 【java】开发——《并发编程》

    目录 一.jmm 二.并发了什么 1.只有一个核(单核)并发还有没有意义 2.单核,还有什么可见性问题 3.并发和并行 三.volitaile 1.变量的可见性问题 2.原因是什么 3.本次修改的变量直接刷到主内存 4.声明其他内存对于这个地址的缓存无效 四.happens-befo 1.顺序性问题 五.volitaile+cas 1.原

    2024年02月22日
    浏览(50)
  • Java-并发编程-进阶篇

    在上一篇幅中对并发编程进行了简单介绍:并发与并行,进程与线程,以及并发编程的简单代码 但是在企业中往往并不能解决实际问题,例如: 1.synchronized在企业开发中会大大降低系统的性能,有什么解决方式,或者其他的替代方案 2.当线程被创建并启动以后,它既不

    2024年02月06日
    浏览(64)
  • Java并发编程-volatile

    volatile 是 java 虚拟机提供的一种轻量级的同步机制,它有三个重要的特性: 保证可见性 不保证原子性 禁止指令重排 要理解这三个特性,就需要对 JMM (JAVA内存模型)有一定的了解才行。 主要解决的问题: JVM中,每个线程都会存在本地内存,本地内存是公共内存的副本,各

    2024年02月06日
    浏览(42)
  • Java并发编程实战

    2023年06月19日
    浏览(51)
  • Java并发编程面试题

    目录 一、线程、进程、程序 二、线程状态  三、线程的七大参数 四、线程有什么优缺点? 五、start 和 run 方法有什么区别? 六、wait 和 sleep的区别? 七、lock与synchronized的区别 八、Volatile是线程安全的吗?底层原理是什么? 九、synchronized作用和底层原理? 十一、Thre

    2024年02月12日
    浏览(59)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包