java多线程系列19-java的内存模型

并发编程中,有两个关键问题:线程之间如何通信和同步。

1.线程之间的通信

通信指线程之间如何交换信息。线程之间有两种通信机制:共享内存和消息传递。
(1)共享内存
线程之间共享程序的公共状态,通过读写内存中的公共状态进行隐式通信。
(2)消息传递
通过发送消息进行显示通信

2.线程之间的同步

共享内存模型中,同步是显示的。而消息传递中同步是隐式的,因为发送消息肯定在接收之前。
java中采用的是共享内存模型。

3.重排序

为了提高性能,编译器和处理器常常对指令做重排序。重排序分为三类:

  • 编译器重排序:编译器在不改变单线程语义的情况下,对语句重排序。
  • 指令集并行重排序:如果不存在数据依赖性,处理器可以改变语句的机器指令的执行顺序,将多条指令并行执行。
  • 内存系统的重排序:由于处理器使用缓存和读写缓冲区,这使得加载和存储操作看上去可能是乱序执行。
    对于内存可见性问题:JMM的编译器重排序规则会禁止特定类型的编译器重排序。对于处理器重排序,JMM的处理器重排序规则会要求在编译器在生成指令序列时,插入特定的内存屏障。

3.1 内存屏障类型

(1)LoadLoad Barriers
确保Load1数据的装载先于Load2及所有后续装载指令的装载
(2)StoreStore Barriers
确保Store1数据对其他处理器的可见性先于Store2及所有后续存储指令的存储
(3)LoadStore Barriers
确保Load1数据的装载先于Store2及所有后续存储指令的存储
(3)StoreLoad Barriers
确保Store1数据对其他处理器的可见性先于Load2及所有后续装载指令的装载.该指令会使该屏障之前的所有内存访问指令(存储和装载)完成之后,才执行屏障之后的指令

3.2 Happens-Before

JMM中如果一个操作的执行结果需要对另外一个操作可见。那么这两个操作之间必须存在Happens-Before原则。上诉两个操作可以在同一个线程,也可以在不同线程。

  • 程序顺序规则:一个线程中的每个操作,Happens-Before该线程中的任意后续操作
  • 监视器锁原则:对个锁的解锁,Happens-Before随后对这个锁的加锁
  • volatile变量原则:对一个volatile域的写,Happens-Before任意后续对这个volatile域的读
  • 传递性:AHappens-BeforeB,且BHappens-BeforeC,则AHappens-BeforeC。
  • start规则:如果线程的start操作Happens-Before于线程B的任意操作
  • join操作线程A执行操作线程B的join,那么线程B的任意操作Happens-BeforeA从B的join方法返回
    Happens-Before并不是说一个操作必须在后续一个操作之前执行,仅仅要求前一个操作的结果对后一个操作可见

3.3 数据依赖性

编译器和处理器在重排序时,对于会遵守数据依赖性,编译器和处理器不会改变存在数据依赖关系的两个操作的执行顺序。这里说的数据依赖是单个线程,不同线程数据依赖不再考虑之内。

3.4 as-if-serial

不管怎么重排序,单线程的结果不能改变

3.5 final域的重排序

锁和volatile重排序之前已经说过。这个说下final域。对于flnal域,编译器和处理器要遵守两个重排序规则:
(1)在一个构造函数内对一个final域的写入,与随后将这个构造函数对象引用赋给另一个引用变量,这两个操作不能重排序。编译器会在final域的写之后,在构造函数return之前,插入一个StoreStore屏障,用来禁止处理器把final域的写重排序到构造函数之外。
(2)初次读一个包含final域对象的引用与随后读这个final域,这两个操作之间不能重排序。编译器还在final域的读操作前面插入一个LoadLoad屏障。

4.顺序一致性模型

JMM对正确同步的多线程程序的内存一致性做了如下保证:
如果程序正确同步,程序的执行结果具有顺序一致性。即程序的执行结果与该程序在顺序一致性内存模型中的结果相同。
顺序一致性模型有两大特性:
(1)一个线程中的所有操作必须按照程序的顺序来执行
(2)不管线程是否同步,所有线程只能看到一个单一的操作执行顺序。在顺序一致性模型中,每个操作都必须原子且立即对所有线程可见。
但JMM中没有这个保证,如果线程不正确同步。
内存一致性模型和JMM模型区别:
(1)顺序一致性模型保证单线程内的操作按程序顺序执行,而JMM不保证
(2)顺序一致性模型保证所有线程看到一致的操作结果,JMM不保证
(3)JMM不保证对64位的long和double变量的写有原子性,而顺序一致性对所有的内存读写都保证原子性

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值