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

java内存模型

2016-03-10 09:34 447 查看
多线程之间的通信主要要解决的两个问题:

线程之间的通信;共享内存模型,隐式的,整个 通信过程是透明的

线程之间的同步:在共享内存的并发模型里,显式的

JVM

堆:存放的是全局变量,实例域,静态域,数组元素

栈:


并发编程过程中的三个原则:

1、原子性

2、有序性

重排序:

编译器级别:1、编译器在不改变线程语义的前提下进行排序,为了防止编译器的排序可以设定内存壁障,强迫编译器不进行排序

处理器级别:2、数据不具有依赖性的话,可以多条指令并行执行

处理器级别:3、内存系统的重排序,处理器使用load/write的时候可能是乱序执行的

3、可见性


为了保证内存的可见性,Java编译器在生成指令序列的时候会在适当的位置插入内存屏障,来禁止特定类型的处理器进行重排序

happens-before的规则:

程序顺序规则:在一个线程中每一个happens-before先于该线程的每一个后续操作(每一个前面的操作优先于后面的操作)

监视器锁规则:在线程中每一个线程的unlock优先于后续线程的lock操作

volatile变量规则:对一个volatile域的写操作happens-before,这个volatile域变量的读操作

传递性:A happens-before B, B happens-before C; ——>A happens-befores C

重排序:

1、数据依赖性:两个操作同时访问两个变量,而且这两个变量中有一个是写操作,那么这两个操作之间就存在着数据依赖性
rw型:写后读型,a = 1, b = a,在完成对a的内存写入操作之后,再执行读操作
rr:a = 1, a = 3;在执行完写操作之后,再执行写操作
wr:a = b, b = 4;先执行读操作然后执行写操作
上述的情况在重排序的时候一定要遵循数据依赖性【针对的是单线程的情况,在多线程中可能还是会有问题】

2、as-if-serial语义:单线程不管怎么排序,程序的执行结果都不能改变
遵守as-if-serial语义:编译器,处理器不会对存在数据依赖的变量进行重排序
数据不存在依赖关系可能会被重排序


A happens-before B:一定是A发生在B之前吗?

JMM(Java内存模型):要求前一个的操作对后一个操作是可见的,要求前一个的执行结果必须发生在第二个操作的之前。

数据竞争:

在一个线程中写一个变量

在另一个线程中读一个变量

而且读和写没有通过同步来排序
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: