Java多线程:“JUC原子类”04之AtomicReference原子类
当前位置:以往代写 > JAVA 教程 >Java多线程:“JUC原子类”04之AtomicReference原子类
2019-06-14

Java多线程:“JUC原子类”04之AtomicReference原子类

Java多线程:“JUC原子类”04之AtomicReference原子类

副标题#e#

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());
    }
}


#p#副标题#e#

说明:

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()实际上是挪用"=="去较量两个工具,即较量两个工具的地 址是否相等。

查察本栏目

    关键字:

在线提交作业