AtomicInteger是一个int的包装类,线程安全。实现线程安全的方式主要是用到了CAS和volatile
1. volatile
private volatile int value;
volatile的作用:可见性。
一般情况下,变量值存在主内存里面。当新建了一个线程的时候,线程的工作内存从主内存中拷贝变量。当工作内存中的值发生变化的时候会刷新到主内存里面。但是有可能出现线程1改变了变量值,刷新到主内存,但是线程2用的还是自己的工作内存的旧值。从而导致数据不一致。
通过加上volatile,线程直接将工作内存中的变量置为无效,去主内存中读取新值。
volatile的另一作用:禁止指令重排
禁止指令重排使用的是内存屏障
但是volatile不能保证操作的原子性,于是有了cas
2. CAS
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
CAS的作用:原子性
cas就是compare and swap,有一个内存值V,预期值A,更新值B,如果A和V相等的时候就会更新为值B。
public final int getAndAddInt(Object var1, long var2, int var4) {
int var5;
do {
var5 = this.getIntVolatile(var1, var2);
// 这个就是自旋锁
} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
return var5;
}
cas与自旋锁:
自旋锁就是while循环,一直循环到成功为止。