zoukankan      html  css  js  c++  java
  • 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。 
  • 相关阅读:
    Python学习笔记 第四天
    Python学习笔记 第三天
    linux系统优化(CentOS7)
    ARMS踩坑合集
    zabbix报错合集(附解决方法)
    keepalived
    ansible
    nginx
    安装虚拟机
    linux发展、redhat与centos的区别
  • 原文地址:https://www.cnblogs.com/Hermioner/p/9905284.html
Copyright © 2011-2022 走看看