AtomicInteger作为一个线程安全类,在多线程环境下做计数器是一个很好的选择
AtomicInteger的线程可见性靠volatile关键字保证,递增或者递减的顺序性靠jdk的Unsafe类来实现
成员变量
private static final Unsafe unsafe = Unsafe.getUnsafe();
//对象偏移量
private static final long valueOffset;
//计数变量
private volatile int value;
初始化对象偏移量
static {
try {
valueOffset = unsafe.objectFieldOffset
(AtomicInteger.class.getDeclaredField("value"));
} catch (Exception ex) { throw new Error(ex); }
}
AtomicInteger常用的方法有:get set getAndIncrement getAndDecrement getAndAdd incrementAndGet decrementAndGet addAndGet
public final int get() {
return value;
}
public final void set(int newValue) {
value = newValue;
}
public final int getAndIncrement() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return current;
}
}
public final int getAndDecrement() {
for (;;) {
int current = get();
int next = current - 1;
if (compareAndSet(current, next))
return current;
}
}
public final int getAndAdd(int delta) {
for (;;) {
int current = get();
int next = current + delta;
if (compareAndSet(current, next))
return current;
}
}
public final int incrementAndGet() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return next;
}
}
public final int decrementAndGet() {
for (;;) {
int current = get();
int next = current - 1;
if (compareAndSet(current, next))
return next;
}
}
public final int addAndGet(int delta) {
for (;;) {
int current = get();
int next = current + delta;
if (compareAndSet(current, next))
return next;
}
}
从代码中可知 ,get、set这类直接获取值与设置值的方法由于不需要运算,直接依赖volatile的线程可见性特性即可实现,而递增递减这些方法需要运算,jdk利用了cas方式实现,先用普通运算符计算出结果,再利用Unsafe 类cas方式设置结果,失败则重新运算与设置,成功即退出