JVM内存模型1

1、并发编程的两个关键问题:线程通信和线程同步

    线程通信的方式:共享内存和消息传递 内存共享模式是隐式进行通信的,而消息传递则是显示进行通信的

    线程同步:用于控制线程间操作发生的相对顺序的机制,共享内存模式中线程同步是显示发生的,而消息传递中线程同步则是隐式发生的。

JAVA采用的是共享内存的模型进行线程间通信和同步的。

2、JAVA内存

    在JAVA中,所有实例域、静态域和数组元素都存储在堆内存中,而堆内存则是在多个线程中进行内存共享的,

    局部变量,方法定义参数,以及异常处理参数不会再线程之间共享,是线程独有的,因此不会再多个线程中共享,也不会有线程间的可见性问题。

3、Java内存模型

    Java线程之间的通信由Java内存模型(本文简称为JMM)控制,JMM决定一个线程对共享变量的写入何时对另一个线程可见。从抽象的角度来看,JMM定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存(Main Memory)中,每个线程都有一个私有的本地内存(Local Memory),本地内存中存储了该线程以读/写共享变量的副本。本地内存是JMM的一个抽象概念,并不真实存在。它涵盖了缓存、写缓冲区、寄存器以及其他的硬件和编译器优化。

4、重排序

    1、编译器优化的重排序:

            编译器在不改变单线程语义的情况下,可以重新安排语句的执行顺序

    2、指令级并行的重排序:

            现代处理器采用了指令级并行技术来将多条指令重叠执行,如果不存在数据依赖性,处理器可以改变语句对应的机器指令的执行顺序。    ——这里应该指的就是流水线技术导致的指令并行的重排序

    3、内存系统的重排序

            由于处理器使用缓存和读/写缓冲区,这使得加载和存储操作看上去可能是乱序在执行。

        上述的1属于编译器重排序,2和3属于处理器重排序。这些重排序可能会导致多线程程序出现内存可见性问题。对于编译器,JMM的编译器重排序规则会禁止特定类型的编译器重排序(不是所有的编译器重排序都要禁止)。对于处理器重排序,JMM的处理器重排序规则会要求Java编译器在生成指令序列时,插入特定类型的内存屏障(Memory Barriers,Intel称之为Memory Fence)指令,通过内存屏障指令来禁止特定类型的处理器重排序。

    4、处理器的重排序

        

     常见的处理器允许store-load的重排序,不允许有数据依赖的重排序。处理器重排序产生问题是因为每个处理器都要一个写缓冲区,而写缓冲区对于其他处理器来说不是透明的,且写缓冲区是批量处理的,因此可能重排序会产生问题。

    

        StoreLoad Barriers是一个“全能型”的屏障,它同时具有其他3个屏障的效果。现代的多处理器大多支持该屏障(其他类型的屏障不一定被所有处理器支持)。执行该屏障开销会很昂贵,因为当前处理器通常要把写缓冲区中的数据全部刷新到内存中(Buffer Fully Flush)。

5、as-if-serial语义

        as-if-serial语义的意思是:不管怎么重排序(编译器和处理器为了提高并行度),(单线程)程序的执行结果不能被改变。编译器、runtime和处理器都必须遵守as-if-serial语义

6、未同步的程序在JMM中的执行顺序

    A、顺序一致性模型保证了单线程内的操作会按照程序的顺序执行,而JMM不保证单线程内的操作会按照程序的顺序执行(比如多线程程序在临界区内的重排序)

    B、顺序一致性模型保证所有线程只能看到一致的操作顺序,而JMM不保证所有线程能看到一致的操作执行顺序

    C、JMM不保证对64位的long型和double型的变量写操作具有原子性,而顺序一致性模型保证对所有的内存读/写操作都具有原子性(因为64位的变量一般会分解成2次32位变量的读写,因此不具有一致性,但是现在JMM要求读变量必须具有一致性,也就是说64位的读也是原子的,但是写变量建议具有一致性,这是为了性能考量)

转载于:https://my.oschina.net/guanhe/blog/2222702

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值