线程安全之可见性问题

一.可见性问题

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修饰的变量所有相关的指令都不做指令重排
发布了53 篇原创文章 · 获赞 42 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_42815122/article/details/104398316