JAVA内存模型、指令重排序、happens-before原则(并发编程篇)

目录

 

硬件内存模型

Java线程与硬件处理器关系

java内存模型

工作空间与主内存之间的交互

并发编程三个特性

并发编程的特性保证

 


硬件内存模型

 

目前的CPU为了提高性能,CPU不会直接会内存交互而是先与缓存交互,仅当读取不到才与内存进行交互;

特点:越靠近cpu速度越快,L1>L2>L3>内存;

那么就会存在一个问题,在并发情况下,CPU读取的值可能不一样,缓存一致性问题怎么解决?

①  锁总线:通过给总线加锁,当某个操作操作该某一共享变量时,其他CPU禁止访问内存;

         缺点:锁的颗粒太大了,影响性能,降低CPU的吞吐量。

② 缓存一致性协议(MESI):当CPU写数据时,如果发现操作的变量是共享变量,通过总线出发总线的嗅探机制,

会发出信号通知其他CPU将该变量的缓存行置为无效状态,因此当其他CPU需要读取这个变量时,

发现自己缓存中缓存该变量的缓存行是无效的,那么它就会从内存重新读取。

 

Java线程与硬件处理器关系

java内存模型

java内存模型(Java Memory Model,JMM)是java虚拟机规范定义的,是一个抽象模型概念,用来屏蔽掉java程序在各种不同的硬件和操作系统对内存的访问的差异,这样就可以实现java程序在各种不同的平台上都能达到内存访问的一致性。

工作空间与主内存之间的交互

java内存中线程的工作内存和主内存的交互是由java虚拟机定义了如下的8种操作来完成的,每种操作必须是原子性的。

①  lock(锁定):作用于主内存的变量,一个变量在同一时间只能一个线程锁定,该操作表示这条线成独占这个变量;

② unlock(解锁):作用于主内存的变量,表示这个变量的状态由处于锁定状态被释放,这样其他线程才能对该变量进行锁定;

③ read(读取):作用于主内存变量,表示把一个主内存变量的值传输到线程的工作内存,以便随后的load操作使用;

④ load(载入):作用于线程的工作内存的变量,表示把read操作从主内存中读取的变量的值放到工作内存的变量副本中

(副本是相对于主内存的变量而言的);

⑤ use(使用):作用于线程的工作内存中的变量,表示把工作内存中的一个变量的值传递给执行引擎,每当虚拟机遇到一个

需要使用变量的值的字节码指令时就会执行该操作;

⑥ assign(赋值):作用于线程的工作内存的变量,表示把执行引擎返回的结果赋值给工作内存中的变量,每当虚拟机遇到

一个给变量赋值的字节码指令时就会执行该操作;

⑦ store(存储):作用于线程的工作内存中的变量,把工作内存中的一个变量的值传递给主内存,以便随后的write操作使用;

⑧ write(写入):作用于主内存的变量,把store操作从工作内存中得到的变量的值放入主内存的变量中。

 

并发编程三个特性

原子性:即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行;

可见性:指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值;

有序性:即程序执行的顺序按照代码的先后顺序执行;

              编译器和处理器为了执行效率可能会编译器重排序、指令重排序。

 

并发编程的特性保证

①  JMM与原子性:

             Synchronized

             JUC   Lock的lock

② JMM与可见性:

                                    volatile:在JMM模型上实现MESI协议

                                    synchronized:加锁

③ JMM与有序性:

    as-if-serial语义:在不存在依赖关系的情况下允许编译器和处理器的指令重排序(单线程);

    happens-before原则:

    程序顺序原则:前一个操作对后一个操作可见,且前一个操作排在后一个前面,如果前一个操作不需对后一个可见,那么JMM

    允许进行重排序;

    锁原则:后一次加锁必须等前一次的释放锁;

    volatile原则:编译器在生成字节码时,通过在指令序列中插入内存屏障禁止重排序,从而保证有效性;

    传递原则:A--->B   B-->C      推导出   C--->A

   JMM基于保守策略插入内存屏障规则如下:

                1.在每个volatile写操作的前面插入一个StoreStore屏障。

                2.在每个volatile写操作的后面插入一个StoreLoad屏障。

                3.在每个volatile读操作的前面插入一个LoadLoad屏障。

                4.在每个volatile读操作的后面插入一个LoadStore屏障。

 

                               

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值