JMM三大特性:可见性,原子性,有序性.
可见性
volatile轻量级。
保证可见性代码验证:
结果:没有输出mission is over。
加上volatile
结果:有一个线程修改了值,其他的线程会收到通知,立马输出。
总结:
原子性
vlolatile不保证原子性
代码验证:
如果正常能保证原子性,结果应该为20000,运行多次都没达到20000。
1.因为每个线程初始都是把开始值为0放入自己的工作内存,线程1把值增加为2写入主内存,线程2把值增加成1也写回主内存,就会覆盖线程1的值,所以最终会出现值不为20000的结果。
2.
解决:
解决一:synchronized可以保证原子性。
解决二:使用juc下面的atomic
有序性
单线程不会出现,多线程才会有出现这个问题
例子一:
由于是多线程,会对指令重排,会有不同的结果。
例子二:
顺序执行结果为6.
但是再多线程,指令重排后,可能先执行 flag=true ,然后执行a=a+5 最后答案为5.
总结:
哪里地方用到volatile?
多线程环境下,单例出现了问题。
解决:加synchronized
解决二:
如果不加volatile的话,因为对象实例化有3步,如果发生了指令重排,获取的instance对象可能还没完成初始化对象,为null。所有需要加上volatile。