AtomicReference源码解析和使用

AtomicReference作用

AtomicReference是作用是对”对象”进行原子操作。
提供了一种读和写都是原子性的对象引用变量。原子意味着多个线程试图改变同一个AtomicReference(例如比较和交换操作)将不会使得AtomicReference处于不一致的状态。

AtomicReference源码

public class AtomicReference implements Serializable {
    private static final long serialVersionUID = -1848883965231344442L;
    private static final Unsafe unsafe = Unsafe.getUnsafe();//通过 unsafe 实现原子操作
    private static final long valueOffset;
    private volatile V value;//通过 volatile 实现原子操作

    public AtomicReference(V var1) {
        this.value = var1;
    }

    public AtomicReference() {
    }

    //通过 volatile 实现原子操作
    public final V get() {
        return this.value;
    }

    //不是原子操作-慎用
    public final void set(V var1) {
        this.value = var1;
    }

    //通过 unsafe 实现原子操作
    public final void lazySet(V var1) {
        unsafe.putOrderedObject(this, valueOffset, var1);
    }

    //通过 unsafe 实现原子操作
     /**
         * var1当前值:拿当前值value和var1值去比较,如果相等返回true并更新值为var2期望值
         * var2期望值:如果返回true则更新为期望值,如果返回false则不更新值
         */
    public final boolean compareAndSet(V var1, V var2) {
        return unsafe.compareAndSwapObject(this, valueOffset, var1, var2);
    }

    //通过 unsafe 实现原子操作
    public final boolean weakCompareAndSet(V var1, V var2) {
        return unsafe.compareAndSwapObject(this, valueOffset, var1, var2);
    }

    //通过 unsafe 实现原子操作
    public final V getAndSet(V var1) {
        return unsafe.getAndSetObject(this, valueOffset, var1);
    }

    //.....省略.....
}

volatile:多线程读写过程中能够保持它们的可见性。即要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。

value是volatile类型,保证value值永远是最新的value值,线程在操作value时不会被中断。

通过Unsafe.compareAndSwapObject设置的value,保证操作是原子性的,线程在操作value时不会被中断。

AtomicReference示例

先定义一个People类

People类

public class People {
    private String name;
    private int age;

    public People(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "People{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

入口函数

public class MainDemo {
    public static void main(String[] args) {
        People people1 =new People("Bom", 0);
        People people2 =new People("Tom",10);

        //先初始化一个值,如果不初始化则默认值为null
        AtomicReference reference = new AtomicReference<>(people1);
        People people3 = reference.get();
        if (people3.equals(people1)) {
            System.out.println("people3:" + people3);
        } else {
            System.out.println("else:" + people3);
        }

        /**
         * 当前值:拿当前值和reference.get()获取到的值去比较,如果相等则true并更新值为期望值
         * 期望值:如果返回true则更新为期望值,如果返回false则不更新值
         */
        boolean b = reference.compareAndSet(null, people2);
        System.out.println("myClass.main-"+b+"--"+reference.get());

        boolean b1 = reference.compareAndSet(people1, people2);
        System.out.println("myClass.main-"+b1+"--"+reference.get());


        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Thread1-----------");

                People people = reference.get();
                people.setName("Tom1");
                people.setAge(people.getAge()+1);
                reference.getAndSet(people);
                System.out.println("Thread1:"+reference.get().toString());
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Thread2-----------");

                People people = reference.get();
                people.setName("Tom2");
                people.setAge(people.getAge()+1);
                reference.getAndSet(people);
                System.out.println("Thread2:"+reference.get().toString());
            }
        }).start();

    }
}

打印结果

people3:People{name='Bom', age=0}
myClass.main-false--People{name='Bom', age=0}
myClass.main-true--People{name='Tom', age=10}
Thread2-----------
Thread2:People{name='Tom2', age=11}
Thread1-----------
Thread1:People{name='Tom1', age=12}

你可能感兴趣的:(AtomicReference源码解析和使用)