Java多线程系列---“JUC原子类”06之 AtomicLongFieldUpdater原子类

Posted Hermioner

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java多线程系列---“JUC原子类”06之 AtomicLongFieldUpdater原子类相关的知识,希望对你有一定的参考价值。

转自:http://www.cnblogs.com/skywang12345/p/3514635.html (含部分修改)

概要

AtomicIntegerFieldUpdater, AtomicLongFieldUpdater和AtomicReferenceFieldUpdater这3个修改类的成员的原子类型的原理和用法相似。本章以对基本类型的原子类进行介绍。内容包括:

  • AtomicLongFieldUpdater介绍和函数列表
  • AtomicLongFieldUpdater示例
  • AtomicLongFieldUpdater源码分析(基于JDK1.7.0_40)

AtomicLongFieldUpdater介绍和函数列表

AtomicLongFieldUpdater可以对指定"类的 \'volatile long\'类型的成员"进行原子更新。它是基于反射原理实现的。

AtomicLongFieldUpdater函数列表

// 受保护的无操作构造方法,供子类使用。
protected AtomicLongFieldUpdater()

// 以原子方式将给定值添加到此更新器管理的给定对象的字段的当前值。
long addAndGet(T obj, long delta)
// 如果当前值 == 预期值,则以原子方式将此更新器所管理的给定对象的字段设置为给定的更新值。
abstract boolean compareAndSet(T obj, long expect, long update)
// 以原子方式将此更新器管理的给定对象字段当前值减 1。
long decrementAndGet(T obj)
// 获取此更新器管理的在给定对象的字段中保持的当前值。
abstract long get(T obj)
// 以原子方式将给定值添加到此更新器管理的给定对象的字段的当前值。
long getAndAdd(T obj, long delta)
// 以原子方式将此更新器管理的给定对象字段当前值减 1。
long getAndDecrement(T obj)
// 以原子方式将此更新器管理的给定对象字段的当前值加 1。
long getAndIncrement(T obj)
// 将此更新器管理的给定对象的字段以原子方式设置为给定值,并返回旧值。
long getAndSet(T obj, long newValue)
// 以原子方式将此更新器管理的给定对象字段当前值加 1。
long incrementAndGet(T obj)
// 最后将此更新器管理的给定对象的字段设置为给定更新值。
abstract void lazySet(T obj, long newValue)
// 为对象创建并返回一个具有给定字段的更新器。
static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName)
// 将此更新器管理的给定对象的字段设置为给定更新值。
abstract void set(T obj, long newValue)
// 如果当前值 == 预期值,则以原子方式将此更新器所管理的给定对象的字段设置为给定的更新值。
abstract boolean weakCompareAndSet(T obj, long expect, long update)

举例说明:

 1 // LongTest.java的源码
 2 import java.util.concurrent.atomic.AtomicLongFieldUpdater;
 3 
 4 public class LongFieldTest {
 5     
 6     public static void main(String[] args) {
 7 
 8         // 获取Person的class对象
 9         Class cls = Person.class; 
10         // 新建AtomicLongFieldUpdater对象,传递参数是“class对象”和“long类型在类中对应的名称”
11         AtomicLongFieldUpdater mAtoLong = AtomicLongFieldUpdater.newUpdater(cls, "id");
12         Person person = new Person(12345678L);
13 
14         // 比较person的"id"属性,如果id的值为12345678L,则设置为1000。
15         mAtoLong.compareAndSet(person, 12345678L, 1000);
16         System.out.println("id="+person.getId());
17     }
18 }
19 
20 class Person {
21     volatile long id;
22     public Person(long id) {
23         this.id = id;
24     }
25     public void setId(long id) {
26         this.id = id;
27     }
28     public long getId() {
29         return id;
30     }
31 }
View Code

运行结果

id=1000

下面分析LongFieldTest.java的流程。

1. newUpdater()
newUpdater()的源码如下:

复制代码
public static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass, String fieldName) {
    Class<?> caller = Reflection.getCallerClass();
    if (AtomicLong.VM_SUPPORTS_LONG_CAS)
        return new CASUpdater<U>(tclass, fieldName, caller);
    else
        return new LockedUpdater<U>(tclass, fieldName, caller);
}
复制代码
说明:newUpdater()的作用是获取一个AtomicIntegerFieldUpdater类型的对象。
它实际上返回的是CASUpdater对象,或者LockedUpdater对象;具体返回哪一个类取决于JVM是否支持long类型的CAS函数。CASUpdater和LockedUpdater都是AtomicIntegerFieldUpdater的子类,它们的实现类似。下面以CASUpdater来进行说明。

 

CASUpdater类的源码如下:

public boolean compareAndSet(T obj, long expect, long update) {
    if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
    return unsafe.compareAndSwapLong(obj, offset, expect, update);
}
说明:它实际上是通过CAS函数操作。如果类的long对象的值是expect,则设置它的值为update。 

 

以上是关于Java多线程系列---“JUC原子类”06之 AtomicLongFieldUpdater原子类的主要内容,如果未能解决你的问题,请参考以下文章

Java多线程系列---“JUC原子类”04之 AtomicLongArray原子类

Java多线程系列---“JUC原子类”05之 AtomicReference原子类

Java多线程系列---“JUC原子类”01之 原子类的实现(CAS算法)

Java多线程系列--“JUC线程池”01之 线程池架构

java 多线程系列---JUC原子类之AtomicLong原子类

java多线程系类:JUC原子类:05之AtomicIntegerFieldUpdater原子类