java并发包 java.util.concurrent
的原子类都存放在
java.util.concurrent.atomic
下
AtomicInteger中的常用方法:
public final int get() //获取当前的值
public final int getAndSet(int newValue)//获取当前的值,并设置新的值
public final int getAndIncrement()//获取当前的值,并自增
public final int getAndDecrement() //获取当前的值,并自减
public final int getAndAdd(int delta) //获取当前的值,并加上预期的值
boolean compareAndSet(int expect, int update) //如果输入的数值等于预期值,则以原子方式将该值设置为输 入值(update)
public final void lazySet(int newValue)//最终设置为newValue,使用 lazySet 设置之后可能导致其他线程 在之后的一小段时间内还是可以读到旧的值。
使用
AtomicInteger
之后,不用对
increment() 等
方法加锁也可以保证线程安全。
AtomicInteger
线程安全原理简单分析
AtomicInteger
类的部分源码:
// setup to use Unsafe.compareAndSwapInt for updates(更新操作时提供“比较并替换”的作用) private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long valueOffset;
static {
try {valueOffset = unsafe.objectFieldOffset(AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) {
throw new Error(ex);
}
}
private volatile int value;
AtomicInteger
类主要利用
CAS (compare and swap) + volatile
和
native
方法来保证原子操作,从而避免
synchronized
的高开销,执行效率大为提升。
CAS
的原理是拿期望的值和原本的一个值作比较,如果相同则更新成新的值。
UnSafe
类的
objectFieldOffffset()
方法
是一个本地方法,这个方法是用来拿到
“
原来的值
”
的内存地址,返回值是
valueOffffset
。另外
value
是一个
volatile
变
量,在内存中可见,因此
JVM
可以保证任何时刻任何线程总能拿到该变量的最新值。