博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java.util.concurrent.atomic与CAS详解
阅读量:7071 次
发布时间:2019-06-28

本文共 4033 字,大约阅读时间需要 13 分钟。

  hot3.png

一、CAS(Compare And Swap)

顾名思义,CAS就是比较与交换。具体解释如下:

CAS 操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。否则,处理器不做任何操作。无论哪种情况,它都会在 CAS 指令之前返回该位置的值。CAS 有效地说明了 “ 我认为位置 V 应该包含值 A;如果包含该值,则将 B 放到这个位置;否则,不要更改该位置,只告诉我这个位置现在的值即可。” 

二、java.ut l.concurrent.atomic

【标量类】:AtomicBoolean,AtomicInteger,AtomicLong,AtomicReference

【数组类】:AtomicIntegerArray,AtomicLongArray,AtomicReferenceArray

【更新器类】:AtomicLongFieldUpdater,AtomicIntegerFieldUpdater,AtomicReferenceFieldUpdater

【复合变量类】:AtomicMarkableReference,AtomicStampedReference

就拿第一组来说,均采用了CAS方式。

三、源码解读

以AtomicInteger为例,源码如下:

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;     ......       /**     * Atomically sets to the given value and returns the old value.     *     * @param newValue the new value     * @return the previous value     */    public final int getAndSet(int newValue) {        for (;;) {            int current = get();            if (compareAndSet(current, newValue))                return current;        }    }    /**     * 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);    }

从上述代码可以看到,AtomicInteger获取value值是通过Unsafe类的objectFieldOffset()方法,然后调用Unsafe类的compareAndSwapInt()方法完成CAS操作。下面看看Unsafe这几个方法,如下:

objectFieldOffset():

/***   * Returns the memory address offset of the given static field.   * The offset is merely used as a means to access a particular field   * in the other methods of this class.  The value is unique to the given   * field and the same value should be returned on each subsequent call.   * 返回指定静态field的内存地址偏移量,在这个类的其他方法中这个值只是被用作一个访问   * 特定field的一个方式。这个值对于 给定的field是唯一的,并且后续对该方法的调用都应该   * 返回相同的值。   *   * @param field the field whose offset should be returned.   *              需要返回偏移量的field   * @return the offset of the given field.   *              指定field的偏移量   */  public native long objectFieldOffset(Field field);

compareAndSwapInt():

/***   * Compares the value of the integer field at the specified offset   * in the supplied object with the given expected value, and updates   * it if they match.  The operation of this method should be atomic,   * thus providing an uninterruptible way of updating an integer field.   * 在obj的offset位置比较integer field和期望的值,如果相同则更新。这个方法   * 的操作应该是原子的,因此提供了一种不可中断的方式更新integer field。   *    * @param obj the object containing the field to modify.   *            包含要修改field的对象   * @param offset the offset of the integer field within obj.   *            obj中整型field的偏移量   * @param expect the expected value of the field.   *            希望field中存在的值   * @param update the new value of the field if it equals expect.   *            如果期望值expect与field的当前值相同,设置filed的值为这个新值   * @return true if the field was changed.   *            如果field的值被更改返回true   */  public native boolean compareAndSwapInt(Object obj, long offset, int expect, int update);

下面看看compareAndSwapInt()方法具体源码,如下:

jbooleansun::misc::Unsafe::compareAndSwapInt (jobject obj, jlong offset, jint expect, jint update){  jint *addr = (jint *)((char *)obj + offset);  return compareAndSwap (addr, expect, update);}
static inline boolcompareAndSwap (volatile jint *addr, jint old, jint new_val){  jboolean result = false;  spinlock lock;  if ((result = (*addr == old)))    *addr = new_val;  return result;}

实现原理就是内存位置的值与期望值相同则将该内存位置的值更新为新值。

Unsafe类的更多源码解释:http://blog.csdn.net/zgmzyr/article/details/8902683

转载于:https://my.oschina.net/eager/blog/727909

你可能感兴趣的文章
聊聊reactor extra的retry
查看>>
reactor-netty中HttpClient对TcpClient的封装
查看>>
数据库安全性操作——操作原则及SQL注入
查看>>
Java网络爬虫实操(9)
查看>>
前面有一个Redux,我们去撩(聊)一下它。
查看>>
iOS开发证书"此证书的签发者无效"解决方法
查看>>
Python实现的通用树结构,支持节点索引,常数时间查找
查看>>
网络传输协议
查看>>
iOS Principle:Category
查看>>
Java多线程之synchronized增强版——ReentrantLock
查看>>
MVP设计模式应该这样掌握
查看>>
Git标签的管理和配置命令别名
查看>>
对UIView,UIWindow和CALayer的理解
查看>>
使用javap分析Java的字符串操作
查看>>
Node.js-Koa2-MongoDB构建RESTful Api
查看>>
饿了么UETool原理初探
查看>>
Android基础 和服务器交互你必须知道的json处理
查看>>
2018阿里云云数据库RDS核心能力演进
查看>>
JAVA面试 基础加强与巩固:反射、注解、泛型等
查看>>
JavaScript 工作原理之六-WebAssembly 对比 JavaScript 及其使用场景
查看>>