zoukankan      html  css  js  c++  java
  • 【java】AtomicReference介绍

    本文转载自:http://www.cnblogs.com/skywang12345/p/3514623.html

     

    概要

    本章对AtomicReference引用类型的原子类进行介绍。内容包括:

    AtomicReference介绍和函数列表

    AtomicReference是作用是对"对象"进行原子操作。

    AtomicReference函数列表

    复制代码
    // 使用 null 初始值创建新的 AtomicReference。
    AtomicReference()
    // 使用给定的初始值创建新的 AtomicReference。
    AtomicReference(V initialValue)
    
    // 如果当前值 == 预期值,则以原子方式将该值设置为给定的更新值。
    boolean compareAndSet(V expect, V update)
    // 获取当前值。
    V get()
    // 以原子方式设置为给定值,并返回旧值。
    V getAndSet(V newValue)
    // 最终设置为给定值。
    void lazySet(V newValue)
    // 设置为给定值。
    void set(V newValue)
    // 返回当前值的字符串表示形式。
    String toString()
    // 如果当前值 == 预期值,则以原子方式将该值设置为给定的更新值。
    boolean weakCompareAndSet(V expect, V update)
    复制代码

    AtomicReference源码分析(基于JDK1.7.0_40)

    在JDK1.7.0_40中AtomicReference.java的源码如下:

    复制代码
    public class AtomicReference<V>  implements java.io.Serializable {
        private static final long serialVersionUID = -1848883965231344442L;
    
        // 获取Unsafe对象,Unsafe的作用是提供CAS操作
        private static final Unsafe unsafe = Unsafe.getUnsafe();
        private static final long valueOffset;
    
        static {
          try {
            valueOffset = unsafe.objectFieldOffset
                (AtomicReference.class.getDeclaredField("value"));
          } catch (Exception ex) { throw new Error(ex); }
        }
    
        // volatile类型
        private volatile V value;
    
        public AtomicReference(V initialValue) {
            value = initialValue;
        }
    
        public AtomicReference() {
        }
    
        public final V get() {
            return value;
        }
    
        public final void set(V newValue) {
            value = newValue;
        }
    
        public final void lazySet(V newValue) {
            unsafe.putOrderedObject(this, valueOffset, newValue);
        }
    
        public final boolean compareAndSet(V expect, V update) {
            return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
        }
    
        public final boolean weakCompareAndSet(V expect, V update) {
            return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
        }
    
        public final V getAndSet(V newValue) {
            while (true) {
                V x = get();
                if (compareAndSet(x, newValue))
                    return x;
            }
        }
    
        public String toString() {
            return String.valueOf(get());
        }
    }
    复制代码

    说明
    AtomicReference的源码比较简单。它是通过"volatile"和"Unsafe提供的CAS函数实现"原子操作。
    (01) value是volatile类型。这保证了:当某线程修改value的值时,其他线程看到的value值都是最新的value值,即修改之后的volatile的值。
    (02) 通过CAS设置value。这保证了:当某线程池通过CAS函数(如compareAndSet函数)设置value时,它的操作是原子的,即线程在操作value时不会被中断。

    AtomicReference示例

    复制代码
    // AtomicReferenceTest.java的源码
    import java.util.concurrent.atomic.AtomicReference;
    
    public class AtomicReferenceTest {
        
        public static void main(String[] args){
    
            // 创建两个Person对象,它们的id分别是101和102。
            Person p1 = new Person(101);
            Person p2 = new Person(102);
            // 新建AtomicReference对象,初始化它的值为p1对象
            AtomicReference ar = new AtomicReference(p1);
            // 通过CAS设置ar。如果ar的值为p1的话,则将其设置为p2。
            ar.compareAndSet(p1, p2);
    
            Person p3 = (Person)ar.get();
            System.out.println("p3 is "+p3);
            System.out.println("p3.equals(p1)="+p3.equals(p1));
        }
    }
    
    class Person {
        volatile long id;
        public Person(long id) {
            this.id = id;
        }
        public String toString() {
            return "id:"+id;
        }
    }
    复制代码

    运行结果

    p3 is id:102
    p3.equals(p1)=false

    结果说明
    新建AtomicReference对象ar时,将它初始化为p1。
    紧接着,通过CAS函数对它进行设置。如果ar的值为p1的话,则将其设置为p2。
    最后,获取ar对应的对象,并打印结果。p3.equals(p1)的结果为false,这是因为Person并没有覆盖equals()方法,而是采用继承自Object.java的equals()方法;而Object.java中的equals()实际上是调用"=="去比较两个对象,即比较两个对象的地址是否相等。

  • 相关阅读:
    java 自定义异常输出信息(使用构造器)
    idea 项目java版本选项位置
    编译、安装rdesktop 1.8.3
    ubuntu下编译源码 make 出现 make: 'Makefile' is up to date.
    ubuntu 图形化界面 gui 桌面版 root登录 sorry,that didn't work.please try again! 抱歉,认证失败。请重试
    MIUI 10 已连接 但无法访问互联网 的解决方案
    idea中 和outline相似的功能
    idea web项目debug模式实时更新按钮不生效原因
    javaweb学习总结二(静态导入、自动拆装箱、增强for与可变参数)
    javaweb学习总结一(eclipse常用快捷键、debug调试以及junit测试框架)
  • 原文地址:https://www.cnblogs.com/lodor/p/7492805.html
Copyright © 2011-2022 走看看