Java 原子类 java.util.concurrent.atomic

Java 原子类 java.util.concurrent.atomic

1、i++为什么是非线程安全的

i++其实是分为3个步骤:获取i的值, 把i+1, 把i+1的结果赋给i

如果多线程执行i++操作,没有同步的话,结果可能不正确

如两个线程同时获取i的值,然后各自+1后,赋给i。正确的情况下i的值应该是加了2,但这里其实加了1而且,前面的结果被覆盖了。

通常做法:synchronized (synchronized方法,synchronized变量), 但这样做效率不是最优的。

2、AtomicInteger的实现

主要依靠:1、volatile 保证了变量的可见性,所有线程不缓存volatile变量,需要时都从内存读取,这样能保证所有数据拿到的值都是最新的。

2、compareAndSet(int expect, int update)判断当前值==expect?当前值=update:错误;

这里做了两步操作,判断跟赋值。但因为cpu提供这样指令的支持,所有能保证这个操作时原子的。

Java代码

    publicclass AtomicIntegerextends Numberimplements java.io.Serializable {privatestaticfinallong serialVersionUID = 6214790243416807050L;// setup to use Unsafe.compareAndSwapInt for updatesprivatestaticfinal Unsafe unsafe = Unsafe.getUnsafe();privatestaticfinallong valueOffset;static { try { valueOffset = unsafe.objectFieldOffset (AtomicInteger.class.getDeclaredField("value"));} catch (Exception ex) { thrownew Error(ex); }} privatevolatileint value;
public class AtomicInteger extends Number implements java.io.Serializable {    private static final long serialVersionUID = 6214790243416807050L;    // 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;

3、AtomicInteger 中的set(int newValue) lazySet(int newValue)

void set(int newValue)

设置为给定值。 直接修改原始值,也就是i=newValue操作。

void lazySet(int newValue) 最后设置为给定值。

延时设置变量值,这个等价于set()方法,但是由于字段是volatile类型的,因此次字段的修改会比普通字段(非volatile字段)有稍微的性能延时(尽管可以忽略),所以如果不是想立即读取设置的新值,允许在“后台”修改值,那么此方法就很有用。如果还是难以理解,这里就类似于启动一个后台线程如执行修改新值的任务,原线程就不等待修改结果立即返回(这种解释其实是不正确的,但是可以这么理解)。

4、AtomicInteger中compareAndSet(int expect, int update) weakCompareAndSet(int expect, int update)

boolean weakCompareAndSet(int expect, int update)如果当前值 == 预期值,则以原子方式将该设置为给定的更新值。JSR规范中说:以原子方式读取和有条件地写入变量但不 创建任何 happen-before 排序,因此不提供与除weakCompareAndSet 目标外任何变量以前或后续读取或写入操作有关的任何保证。大意就是说调用weakCompareAndSet时并不能保证不存在happen-before的发生(也就是可能存在指令重排序导致此操作失败)。但是从Java源码来看,其实此方法并没有实现JSR规范的要求,最后效果和compareAndSet是等效的,都调用了unsafe.compareAndSwapInt()完成操作。

Java代码

    /** * Atomically sets the value to the given updated value* if the current value {@code ==} the expected value.* * @param expect the expected value * @param update the new value * @return true if successful. False return indicates that* the actual value was not equal to the expected value.*/publicfinalboolean compareAndSet(int expect,int update) { return unsafe.compareAndSwapInt(this, valueOffset, expect, update);} /** * Atomically sets the value to the given updated value* if the current value {@code ==} the expected value.* * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>* and does not provide ordering guarantees, so is only rarely an* appropriate alternative to {@code compareAndSet}.* * @param expect the expected value * @param update the new value * @return true if successful. */publicfinalboolean weakCompareAndSet(int expect,int update) { return unsafe.compareAndSwapInt(this, valueOffset, expect, update);}
    /**     * Atomically sets the value to the given updated value     * if the current value {@code ==} the expected value.     *     * @param expect the expected value     * @param update the new value     * @return true if successful. False return indicates that     * the actual value was not equal to the expected value.     */    public final boolean compareAndSet(int expect, int update) {return unsafe.compareAndSwapInt(this, valueOffset, expect, update);    }    /**     * Atomically sets the value to the given updated value     * if the current value {@code ==} the expected value.     *     * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>     * and does not provide ordering guarantees, so is only rarely an     * appropriate alternative to {@code compareAndSet}.     *     * @param expect the expected value     * @param update the new value     * @return true if successful.     */    public final boolean weakCompareAndSet(int expect, int update) {return unsafe.compareAndSwapInt(this, valueOffset, expect, update);    }

人生的小河,总要流过森林,荒漠,

Java 原子类 java.util.concurrent.atomic

相关文章:

你感兴趣的文章:

标签云: