问题3:atomicinteger和volatile等线程安全操作的关键字的理解和使用

线程安全问题的本质其实就是原子性、有序性、可见性
原子性: 和数据库事务中的原子性一样,满足原子性特性的操作是不可中断的,要么全部执行成功要么全部执行失败
有序性: 编译器和处理器为了优化程序性能而对指令序列进行重排序,也就是你编写的代码顺序和最终执行的指令顺序是不一致的,重排序可能会导致多线程程序出现内存可见性问题
可见性: 多个线程访问同一个共享变量时,其中一个线程对这个共享变量值的修改,其他线程能够立刻获得修改以后的值
Volatile被视为轻量级的Synchronized,他实现了可见性不保证原子性,读取volatile变量时首先会从主内存中刷新最新数据,修改变量之后直接将数据写回主内存,volatile关键字能禁止指令重排序,所以volatile能在一定程度上保证有序性。使用volatile不能保证线程安全,因为他只实现了可见性,比如volatile static a=0; a++; 因为a++不具有原子性,如果两个线程同时从主内存中获取到最新的a,然后执行a++之后写回主内存结果就是1而不是2,因此不是线程安全的。

使用条件:
1)对变量的写入操作不依赖变量的当前值,或者保证只有单个线程更新变量
2)该变量不会与其他状态变量一起纳入不变性条件中
3)在访问变量时不需要加锁
AtomicInteger是Java.util.concurrent中实现的原子操作底层就是volatile和CAS 1.首先使用了volatile 保证了内存可见性。2.然后使用了CAS(compare-and-swap)算法 保证了原子性