码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2018-04-29 18:42:29      阅读:171      评论:0      收藏:0      [点我收藏+]

标签:笔记   src   例子   算法   多个   java并发   顺序   AC   java   

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

 

解决方法:

技术分享图片

 

 

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

于是改为下面这种:

 技术分享图片

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

标签:笔记   src   例子   算法   多个   java并发   顺序   AC   java   

原文地址:https://www.cnblogs.com/kz2017/p/8971486.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!