个人笔记--内存可见性和原子变量

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关键字修饰(放在主缓存中 问题还在) 他只能保证内存可见性问题 不能保证原子性问题

 

解决方法:

技术分享图片

 

 

也是一种无锁的非阻塞算法的实现。

于是改为下面这种:

 技术分享图片


以上是关于个人笔记--内存可见性和原子变量的主要内容,如果未能解决你的问题,请参考以下文章

可见性原子性和有序性

原子性内存可见性和重排序——重新认识synchronized和volatile

Java内存模型

voliate怎么保证可见性

Java内存模型之可见性问题

java内存模型的理解