java.util.concurrent源碼閱讀 03 AtomicXXXFieldUpdater

雖然volatile實(shí)現(xiàn)了多線程的可見(jiàn)性, 用于多線程對(duì)某個(gè)變量的修改, 比如bool值的變化, 別的線程立即看到, 可以退出循環(huán)之類的后續(xù)操作. 但是volatile不是線程安全的, 對(duì)其修飾的變量++, 加法減法等操作保證不了線程安全.
為了實(shí)現(xiàn)普通volatile變量的原子操作, java.util.concurrent包提供了AtomicXXXfieldupdater類.
以AtomicIntegerFieldUpdater為例, 實(shí)現(xiàn)普通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();
    }
}

運(yùn)行結(jié)果:

0
2
1
3

多運(yùn)行幾次,可以看到加法是原子操作的.
下面看AtomicIntegerFieldUpdater的源碼.
1.首先是類聲明:

public abstract class  AtomicIntegerFieldUpdater<T> {
    ...
}

可以看到AtomicIntegerFieldUpdater是一個(gè)抽象類.
2.構(gòu)建AtomicIntegerFieldUpdater實(shí)例.

@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類似, 區(qū)別在于AtomicIntegerFieldUpdater需要將操作的對(duì)象作為參數(shù)傳入.
4.最后, 是AtomicIntegerFieldUpdater的內(nèi)部類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相同, 只是多了一個(gè)類訪問(wèn)權(quán)限的判斷.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容