java内存模型相关概念

内容安排:
1、指令执行过程
2、共享变量
3、缓存不一致问题
4、原子性问题
5、可见性问题
6、有序性问题
7、synchronized、Lock

8、java默认的有序性原则

1、指令执行过程
a)从主存中获取变量值
b)复制该值到高速缓存
c)将高速缓存中的值给CPU计算并将结果写入高速缓存
d)将高速缓存中的计算结果写入主存

2、共享变量
多线程公用的变量

3、缓存不一致问题
多线程情况下出现该问题,产生的原因为:
a)线程1将变量x读取至自己的缓存中并准备计算
b)在线程1尚未将返回结果写入内存前,线程2将变量x的值读取到自己的缓存中,也准备计算。(此时线程2的缓存中x的值并不是线程1的计算结果)
c)线程1计算完成后将x的值写入内存
d)线程2计算完成后将x的值写入内存,此时会覆盖线程1的计算结果
两个线程运行结束后发现,线程1的计算其实被覆盖了,相当于无效,从而导致了计算错误。

4、原子性问题
一次运行,要么完成,要么处于操作前的状态
例如:int x=10; //二进制表示  (H)0000 0000 0000 0000 | (L)0000 0000 0000 1010
假设这个复制过程分成两个步骤:1)存高16位的值  2)存低16位的值
那么可能存在的情况:高16位存成功后另一个线程就来都x的值,此时低16位尚未存入,得到的x=0,显然是错误的。
当然,这只是为了说明问题,在几乎所有的语言中简单的复制操作都是遵循原子性操作的,也就是说:只有高低16位都存成功后别的线程才能获取到x的值。

5、可见性问题
共享变量的值修改后会通知其他线程该变量在其内存中的值无效
继续3中缓存不一致的问题:
a)线程1将变量x读取至自己的缓存中并准备计算。
b)在线程1尚未将返回结果写入内存前,线程2将变量x的值读取到自己的缓存中,也准备计算。(此时线程2的缓存中x的值并不是线程1的计算结果)
c)线程1计算完成改变了x的值,此时如果该操作遵循可见性则会通知线程2:x在的值已经改变,宣布线程2中的x的值无效。
d)线程1将计算后的x存入内存中。
d)线程2从内存中重新获取x的值并用于计算并将结果存入内存。
两个线程的运行都是有效的

6、有序性问题
有序:代码按照先后顺序运行
指令重排列:CPU在执行指令时处于优化考虑会将代码进行重排列

例如:
		int i=0;
		boolean runFlag=false;
		
		i=100;                //语句1
		runFlag=true;         //语句2
		
	在执行时语句2可能比语句1先执行,但不管怎么重排列,CPU会保证执行的结果一致。这在单线程中不会有问题,在多线程中情况就不一样了。
	例如:
		线程1:
		initParams();  		      // 1 初始化参数操作
		boolean runFlag=true;     // 2
		
		线程2:
		while(!runFlag){
			sleep(100);
		}
		doSomethingWithParams();  //3 需要用到初始化后的参数

如果两个线程都开启并正常运行,可能存在的情况如下:
语句2别语句1先执行,线程2发现runFlag=true便会跳出等待循环而去执行doSomethingWithParams(),而此时initParams()尚未执行
便会使得doSomethingWithParams()使用的参数并不是初始化后的,这往往导致执行结果莫名其妙又不报错

7、synchronized、Lock
代码同步和锁都能保证变量的可见性和代码的有序性,因为它们保证了同一变量、方法或者代码块同一时间只有一个线程可以修改

8、java默认的有序性原则
happens-before原则:
1)程序次序规则:一个线程内,按照代码顺序,书写在前面的操作先行发生于书写在后面的操作
2)锁定规则:一个unLock操作先行发生于后面对同一个锁的lock操作
3)volatile变量规则:对一个变量的写操作先行发生于后面对这个变量的读操作
4)传递规则:如果操作A先行发生于操作B,而操作B又先行发生于操作C,则可以得出操作A先行发生于操作C
5)线程启动规则:Thread对象的start()方法先行发生于此线程的每个一个动作
6)线程中断规则:对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生
7)线程终结规则:线程中所有的操作都先行发生于线程的终止检测,我们可以通过Thread.join()方法结束、Thread.isAlive()的返回值手段检测到线程已经终止执行
8)对象终结规则:一个对象的初始化完成先行发生于他的finalize()方法的开始

参考:http://www.importnew.com/18126.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值