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

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

解决方法:

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

于是改为下面这种:

 

猜你喜欢

转载自www.cnblogs.com/kz2017/p/8971486.html