虽然volatile实现了多线程的可见性, 用于多线程对某个变量的修改, 比如bool值的变化, 别的线程立即看到, 可以退出循环之类的后续操作. 但是volatile不是线程安全的, 对其修饰的变量++, 加法减法等操作保证不了线程安全.
为了实现普通volatile变量的原子操作, java.util.concurrent包提供了AtomicXXXfieldupdater类.
以AtomicIntegerFieldUpdater为例, 实现普通volatile int变量的原子操作.
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
class Container {
public volatile int no;
}
class Task extends Thread {
private AtomicIntegerFieldUpdater<Container> updater =
AtomicIntegerFieldUpdater.newUpdater(Container.class, "no");
private Container c;
public Task(Container c) {
this.c = c;
}
@Override
public void run() {
System.out.println(updater.getAndIncrement(c));
System.out.println(updater.getAndIncrement(c));
}
}
public class UpdaterUsage {
public static void main (String [] args) {
Container c = new Container();
Task t1 = new Task(c);
Task t2 = new Task(c);
t1.start();
t2.start();
}
}
运行结果:
0
2
1
3
多运行几次,可以看到加法是原子操作的.
下面看AtomicIntegerFieldUpdater的源码.
1.首先是类声明:
public abstract class AtomicIntegerFieldUpdater<T> {
...
}
可以看到AtomicIntegerFieldUpdater是一个抽象类.
2.构建AtomicIntegerFieldUpdater实例.
@CallerSensitive
public static <U> AtomicIntegerFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) {
return new AtomicIntegerFieldUpdaterImpl<U>(tclass, fieldName, Reflection.getCallerClass());
}
3.其余一些抽象方法.
protected AtomicIntegerFieldUpdater() {
}
public abstract boolean compareAndSet(T obj, int expect, int update);
public abstract boolean weakCompareAndSet(T obj, int expect, int update);
public abstract void set(T obj, int newValue);
public abstract void lazySet(T obj, int newValue);
public abstract int get(T obj);
public int getAndSet(T obj, int newValue) {
for (;;) {
int current = get(obj);
if (compareAndSet(obj, current, newValue))
return current;
}
}
public int getAndIncrement(T obj) {
for (;;) {
int current = get(obj);
int next = current + 1;
if (compareAndSet(obj, current, next))
return current;
}
}
public int getAndDecrement(T obj) {
for (;;) {
int current = get(obj);
int next = current - 1;
if (compareAndSet(obj, current, next))
return current;
}
}
public int getAndAdd(T obj, int delta) {
for (;;) {
int current = get(obj);
int next = current + delta;
if (compareAndSet(obj, current, next))
return current;
}
}
public int incrementAndGet(T obj) {
for (;;) {
int current = get(obj);
int next = current + 1;
if (compareAndSet(obj, current, next))
return next;
}
}
public int decrementAndGet(T obj) {
for (;;) {
int current = get(obj);
int next = current - 1;
if (compareAndSet(obj, current, next))
return next;
}
}
public int addAndGet(T obj, int delta) {
for (;;) {
int current = get(obj);
int next = current + delta;
if (compareAndSet(obj, current, next))
return next;
}
}
方法的功能与AtomicInteger类似, 区别在于AtomicIntegerFieldUpdater需要将操作的对象作为参数传入.
4.最后, 是AtomicIntegerFieldUpdater的内部类AtomicIntegerFieldUpdaterImpl, 它继承了AtomicIntegerFieldUpdater.
private static class AtomicIntegerFieldUpdaterImpl<T> extends AtomicIntegerFieldUpdater<T> {
private static final Unsafe unsafe = Unsafe.getUnsafe();
private final long offset;
private final Class<T> tclass;
private final Class cclass;
AtomicIntegerFieldUpdaterImpl(Class<T> tclass, String fieldName, Class<?> caller) {
Field field = null;
int modifiers = 0;
try {
field = tclass.getDeclaredField(fieldName);
modifiers = field.getModifiers();
sun.reflect.misc.ReflectUtil.ensureMemberAccess(
caller, tclass, null, modifiers);
sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
Class fieldt = field.getType();
if (fieldt != int.class)
throw new IllegalArgumentException("Must be integer type");
if (!Modifier.isVolatile(modifiers))
throw new IllegalArgumentException("Must be volatile type");
this.cclass = (Modifier.isProtected(modifiers) &&
caller != tclass) ? caller : null;
this.tclass = tclass;
offset = unsafe.objectFieldOffset(field);
}
private void fullCheck(T obj) {
if (!tclass.isInstance(obj))
throw new ClassCastException();
if (cclass != null)
ensureProtectedAccess(obj);
}
public boolean compareAndSet(T obj, int expect, int update) {
if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
return unsafe.compareAndSwapInt(obj, offset, expect, update);
}
public boolean weakCompareAndSet(T obj, int expect, int update) {
if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
return unsafe.compareAndSwapInt(obj, offset, expect, update);
}
public void set(T obj, int newValue) {
if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
unsafe.putIntVolatile(obj, offset, newValue);
}
public void lazySet(T obj, int newValue) {
if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
unsafe.putOrderedInt(obj, offset, newValue);
}
public final int get(T obj) {
if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
return unsafe.getIntVolatile(obj, offset);
}
private void ensureProtectedAccess(T obj) {
if (cclass.isInstance(obj)) {
return;
}
throw new RuntimeException(
new IllegalAccessException("Class " +
cclass.getName() +
" can not access a protected member of class " +
tclass.getName() +
" using an instance of " +
obj.getClass().getName()
)
);
}
}
总体原理与AtomicInteger相同, 只是多了一个类访问权限的判断.