您的位置:首页 > 编程语言 > Java开发

Java并发之内存模型-JMM

2014-11-29 23:25 381 查看
1、总括
     并发编程模型主要处理两个问题:线程之间如何通信及线程之间如何同步。通信:线程之间以何种机制来交换信息;同步:程序用来控制不同线程之间操作发生相对顺序的机制。

     发生线程安全性的时机:
          变量存储在内存中,变量的计算是在CUP中。如果线程A要对变量a进行计算,需要经过三步:1)把变量a从内存中读取到CPU中,2)对变量a进行计算,3)把变量a写入到内存中。当线程A执行到第二步时,线程B也要对变量a进行计算,这时B从内存中读取到的值就是线程A写入到内存之前的值,脏数据就此产生了。

     在命令式编程中主要有两种通信机制:共享内存和消息传递。

2、共享内存的并发模型:
          通信:线程之间共享内存的公共状态,线程之间通过读-写内存中的共享状态来进行隐式通信。所谓隐式:线程什么时候可以读取共享状态对程序员来说是透明的。
          同步:程序员必须指定某段代码或某个方法必须在线程之间互斥执行。所以说同步是显式的。

3、消息传递的并发模型:
          通信:线程之间没有公共状态,所以线程直接必须明确的发送消息进行显式的通信。
          同步:消息的发送必须在消息的接收之前,因此同步是隐式的。

4、JAVA
     Java的内存模型是共享内存,所以说Java的通信是隐式的,同步是显式的。

5、Java中,所有的实例域、静态域和数组元素都是存储堆中的,堆内存在线程之间是共享的。本地变量(存储在虚拟机栈的局部变量表中)、异常处理器参数不会在线程直接共享。
     另外:在JVM中,虚拟机栈、程序计数器、方法区存储的数据都是线程私有的。随线程而生,随线程而灭。

6、Java线程之间的通信由JMM控制,JMM决定了一个线程对共享变量的写入何时对另一个线程可见。JMM定义了线程和主内存之间的关系:线程之间的共享变量存储在主内存(main memory)中,每个线程都有一个私有的本地内存(Local memory),本地内存中存储了共享变量的副本。本地内存是JMM的一个抽象概念。

7、JMM抽象示意图

     如果线程A要和线程B通信,需要经过以下2个步骤:
            1)线程A把本地内存中的变量更新到主内存中
            2)线程B把主内存中的变量读取到本地内存中

8、下图描述上面两个步骤

本地线程A和B中都有主内存中共享变量的副本X。假设初始三个内存中的值都是0,线程A执行时把更新后X的值(假设是1)临时保存到本地内存中。如果A要和B通信,线程A会把本地内存中修改后的值刷新到主内存中。随后线程B到主内存中读取线程A更新后的X值,此时线程B的本地内存中X的值也是1了。

9、关键词
     编译器优化重排序,指令级并行的重排序、内存系统重排序、处理器重排序、内存屏障。

10、volatile\Synchronized 关键词会屏蔽重排序。

参考资料:infoq.com/深入理解JMM

     

     
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息