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关键字修饰(放在主缓存中 问题还在) 他只能保证内存可见性问题 不能保证原子性问题
解决方法:
也是一种无锁的非阻塞算法的实现。
于是改为下面这种:
原文地址:https://www.cnblogs.com/kz2017/p/8971486.html
时间: 2024-10-07 10:52:01