Java concurrency之AtomicReference原子类_动力节点Java学院整理

所属分类: 软件编程 / java 阅读数: 40
收藏 0 赞 0 分享

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 concurrency之锁_动力节点Java学院整理

这篇文章主要为大家详细介绍了Java concurrency之锁的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Java8新特性之StampedLock_动力节点Java学院整理

本文从synchronized、Lock到Java8新增的StampedLock进行对比分析,对Java8新特性之StampedLock相关知识感兴趣的朋友一起看看吧
收藏 0 赞 0 分享

Java8新特性之lambda的作用_动力节点Java学院整理

我们期待了很久lambda为java带来闭包的概念,但是如果我们不在集合中使用它的话,就损失了很大价值。现有接口迁移成为lambda风格的问题已经通过default methods解决了,在这篇文章将深入解析Java集合里面的批量数据操作解开lambda最强作用的神秘面纱。
收藏 0 赞 0 分享

Java8新特性之Base64详解_动力节点Java学院整理

这篇文章主要为大家详细介绍了Java8新特性之Base64的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Java8新特性之JavaFX 8_动力节点Java学院整理

这篇文章主要介绍了Java8新特性之JavaFX 8的相关知识,非常不错,具有参考借鉴价值,需要的朋友参考下吧
收藏 0 赞 0 分享

将本地jar包安装进入maven仓库(实现方法)

下面小编就为大家带来一篇将本地jar包安装进入maven仓库(实现方法)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

浅谈Java finally语句到底是在return之前还是之后执行(必看篇)

下面小编就为大家带来一篇浅谈Java finally语句到底是在return之前还是之后执行(必看篇)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

基于Java并发容器ConcurrentHashMap#put方法解析

下面小编就为大家带来一篇基于Java并发容器ConcurrentHashMap#put方法解析。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

详解Spring Boot Profiles 配置和使用

本篇文章主要介绍了详解Spring Boot Profiles 配置和使用,具有一定的参考价值,有兴趣的可以了解一下
收藏 0 赞 0 分享

详解Spring Boot 属性配置和使用

本篇文章主要介绍了详解Spring Boot 属性配置和使用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享
查看更多