JAVA并发API源码解析:原子类

来源:互联网 发布:excel下拉菜单选择数据 编辑:程序博客网 时间:2024/06/06 01:16

    在JAVA API的java.util.concurrent.atomic包下提供了一系列以基本类型包装类为基础的并发情况下不需要同步的类(借助硬件相关指令实现)。

    首先看一个例子AutomicInteger:

public class AtomicInteger extends Number implements java.io.Serializable {    private static final long serialVersionUID = 6214790243416807050L;    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;    public AtomicInteger(int initialValue) {        value = initialValue;    }    public AtomicInteger() {    }    public final int get() {        return value;    }    public final void set(int newValue) {        value = newValue;    }    public final void lazySet(int newValue) {        unsafe.putOrderedInt(this, valueOffset, newValue);    }    public final int getAndSet(int newValue) {        for (;;) {            int current = get();            if (compareAndSet(current, newValue))                return current;        }    }    public final boolean compareAndSet(int expect, int update) {        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);    }    public final boolean weakCompareAndSet(int expect, int update) {        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);    }    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;        }    }    public String toString() {        return Integer.toString(get());    }    public int intValue() {        return get();    }    public long longValue() {        return (long)get();    }    public float floatValue() {        return (float)get();    }    public double doubleValue() {        return (double)get();    }}

    源代码中没有volatile或者synchronized这些同步机制也没有锁,其实它的同步是通过硬件指令实现。Integer内部方法不是线程安全的所以并发编程推荐使用AtomicInteger类来替换包装类,但是原子类不是 java.lang.Integer 和相关类的通用替换方法,它们不定义诸如 hashCode 和 compareTo 之类的方法。例如:不提供AtomicDouble,开发人员需要使用 Double.doubleToLongBits 和 Double.longBitsToDouble 转换来保持 double 值。

    此包还包含 Updater 类,该类可用于获取任意选定类的任意选定 volatile 字段上的 compareAndSet 操作。解决volatile字段非原子操作的安全问题。

0 0