个人笔记--内存可见性和原子变量
Posted kz2017
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了个人笔记--内存可见性和原子变量相关的知识,希望对你有一定的参考价值。
jdk1.6以后提供了java并发包。
volatile与内存可见性:
例子:
结果:
结论:
main()线程读取到的td.isFlag并不是true。
这就涉及到了内存可见性问题。
具体原因:
重排序:代码书写的顺序与实际执行的顺序不同。
1. 编译器重排序
2. 指令重排序
3. 内存系统重排序
As-if-serial:
无论如何重排序,程序执行的记过应该与代码顺序执行的结果一致。Java编译器和处理器在运行时都会保证在单线程下遵循这个语言。
补充:jstack可以生成线程快照(jdk/bin)
每一个线程都有单独的内存,只有对一个共享数据进行了操作修改后,才会把更新后的值刷新到主内存中。
但是本例子中,我们使用的是while(true),它的运行速度很快,导致main线程没能读取到线程1修改的值便结束了。于是产生了上面的结果。
这就是内存可见性问题-->当多个线程操作共享数据时,彼此不可见。
解决方法1:
加锁,但是效率太低下了,而且还有其他原因。
这种情况下,我们就可以使用volatile关键字了。
可以把它简单的理解,volatile关键字修饰的变量,就存在主内存中。
原子变量和CAS算法:
结果:
原因:
因为i++有三个步骤 所以这时候不能使用volatile关键字修饰(放在主缓存中 问题还在) 他只能保证内存可见性问题 不能保证原子性问题
解决方法:
也是一种无锁的非阻塞算法的实现。
于是改为下面这种:
以上是关于个人笔记--内存可见性和原子变量的主要内容,如果未能解决你的问题,请参考以下文章