线程安全之可见性问题

一.可见性问题

1.CPU指令重排

Java编程语言为了增强效率,其的语义允许Java编译器和微处理器进行执行优化,
这些优化导致了与其交互的代码不再同步,从而导致出现看似矛盾的行为。

比如代码

		boolean isTrue = true;
        while (isTrue){
            //...
        }

在循环判断执行一定次数,变量isTrue的值一直为true,则CPU就会将该代码进行指令重排

        boolean isTrue = true;
        if (isTrue) {
            //...
        }

变成if(true),这样在变量isTrue的值被更改后,还是不会出现

又比如代码如果在多线程的情况下

		//线程A
		int a = 10;
        a = 20;
        boolean flag = true;

线程B中的代码

	//线程B
	while(flag){
		System.out.println(a);
	}

如果指令重排将flag赋值true指令重排在 a = 20之前的话,输出的结果就会不一样了

2.CPU高速缓存

线程与主内存进行交互,中间还有层CPU高速缓存,而这段进出高速缓存期间也有极小的可能出现数据不一致的问题

二.volatile关键字

何为可见性?

让一个线程对共享变量的修改,能够及时的被其他线程看到 。

volatile为何能实现线程间的可见?

java内存模型中规定:

  1. 禁止缓存,对于volatile修饰的变量,不会走CPU高速缓存
  2. 对于和volatile修饰的变量所有相关的指令都不做指令重排
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值