Java内存模型中的可见性、原子性、有序性

一、可见性

1、什么叫做没有可见性
假设两个线程同时去操作主内存中的对象:
在这里插入图片描述
比如线程1需要去修改主内存中的data值,线程2只需要去读取主内存中的data值:

new Thread1(){
	public void run(){
		data++;
	}
}.start();

new Thread2(){
	public void run(){
		while(data==0){
			Thread.sleep(100);
		}
	}
}.start();

当线程1把data的值改成了1后,线程2不一定会立刻就感觉到data的变化;
很有可能在一定的时间范围内,因为之前线程2已经将data=0加载到自己的工作内存中,所以线程2仍处于sleep状态;
这种data已经被线程1更新了,但是线程2在一段时间内仍然看不见的情况就是不具备可见性。

2、什么叫具有可见性
线程1更新完data后,强制线程2重新读取data的值,获得更新后的data。

二、原子性

假设当两个线程同时对主内存中的对象进行操作,如果有原子性,则线程1操作主内存中的data时,线程2不能对主内存中的data进行操作,保证同一时间只有一个线程对主内存中的data进行操作:
在这里插入图片描述

三、有序性

以一段代码为例:

flag=false;

//线程1
prepare();   //准备资源
flag=true;

//线程2:如果flag为false则一直等待
while(!flag){
	Thread.sleep(1000);
}
execute();   //基于准备好的资源执行操作

对于代码,还有一个问题就是指令重排序,编译器和指令器有时为了提高代码的执行效率,会将指令重排序,比如:

flag=false;

//线程1
flag=true;
prepare();   //准备资源

//线程2:如果flag为false则一直等待
while(!flag){
	Thread.sleep(1000);
}
execute();   //基于准备好的资源执行操作

把flag=true;排到了前面,导致线程2不再等待,而线程1的prepare方法还没有执行完,线程2的execute方法在资源没准备完成的情况下执行,导致代码逻辑出现问题。

具备有序性:不会发生指令重排导致代码异常;
不具备有序性:可能发生指令重排导致异常。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值