volatile关键字 主要是让被修饰的对象能够在内存中及时的可见,修改后及时传递到各个线程的本地内存中。
举一个例子最清晰,A和B线程同时去操作一个 int值 都去加1
如下图:最开始两个线程都从cpu的内存空间中去拿到count的值放到自己的本地内存中
如果不是使用关键字volatile 可能导致如果A线程先执行完后把count值修改成了1并且刷新到了主内存空间,B线程再执行的时候本地内存中的count值还是0,还是拿到0去加1,最终的结果就是count的值还是为1,但是其实,该为2的。
如果使用了关键字 volatile 当A线程修改了count值为1后并刷新到了主的内存空间,这时候B线程强制去主内存取count值,这个时候B执行再执行的时候就会是在1的基础上再加1 变成2.
总结:加volatile关键字:强制每个线程都去主内存中取值。不加volatile:去本地内存取自己的
注意我之前很困惑的地方就是 既然内存可见了为什么还是会出现 两个线程都执行后出现最后的结果还是为1的情况。其实内存可见不保证原子性
↵因为A和B线程如果是先后执行这里的先后是指,相隔时间稍等大一点的那种,比如一秒。这种情况如果只使用volatile可以实现正常的数据相加因为这个不是并发,但是如果A和B线程同时执行的话就会出现一个问题,当其中A在拿到主内存中的0值加1时,B也已经开始拿到主内存中的0值去加1,并发就是同时去执行啥,所以这个时候还不能保证最终的结果会正确。
接下来就是CAS ,比较后再赋值,其实这个就是拿到值后先与原来主内存中的值进行比较再进行赋值,如果和原来的值一样再把新的值赋值进去。这样的话上述问题就能差不多解决了。
上述是我自己的想法和理解 不保证全部正确仅做参考