zoukankan      html  css  js  c++  java
  • Java多线程系列--“JUC原子类”05之 AtomicLongFieldUpdater原子类

    概要

    AtomicIntegerFieldUpdater, AtomicLongFieldUpdater和AtomicReferenceFieldUpdater这3个修改类的成员的原子类型的原理和用法相似。本章以对基本类型的原子类进行介绍。内容包括:
    AtomicLongFieldUpdater介绍和函数列表
    AtomicLongFieldUpdater示例
    AtomicLongFieldUpdater源码分析(基于JDK1.7.0_40)

    转载请注明出处:http://www.cnblogs.com/skywang12345/p/3514623.html

     

    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)
    复制代码

    AtomicLongFieldUpdater示例

    复制代码
    // LongTest.java的源码
    import java.util.concurrent.atomic.AtomicLongFieldUpdater;
    
    public class LongFieldTest {
        
        public static void main(String[] args) {
    
            // 获取Person的class对象
            Class cls = Person.class; 
            // 新建AtomicLongFieldUpdater对象,传递参数是“class对象”和“long类型在类中对应的名称”
            AtomicLongFieldUpdater mAtoLong = AtomicLongFieldUpdater.newUpdater(cls, "id");
            Person person = new Person(12345678L);
    
            // 比较person的"id"属性,如果id的值为12345678L,则设置为1000。
            mAtoLong.compareAndSet(person, 12345678L, 1000);
            System.out.println("id="+person.getId());
        }
    }
    
    class Person {
        volatile long id;
        public Person(long id) {
            this.id = id;
        }
        public void setId(long id) {
            this.id = id;
        }
        public long getId() {
            return id;
        }
    }
    复制代码

    运行结果

    id=1000

    AtomicLongFieldUpdater源码分析(基于JDK1.7.0_40)

    AtomicLongFieldUpdater完整源码

    View Code

    下面分析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。

  • 相关阅读:
    成为 Team Leader 后我最关心的那些事
    《管理的实践》读书心得
    玩黑客学校CTF
    DHCP中继器
    test
    初窥XSS跨站脚本攻击
    TCP/IP模型
    逻辑漏洞-客户端验证的邮箱-Web渗透实例之中国教育部青少年普法网站逻辑漏洞
    逻辑漏洞-支付风险-大疆某处支付逻辑漏洞可1元买无人机
    逻辑漏洞-密码找回之验证码发给了客户端
  • 原文地址:https://www.cnblogs.com/wzyxidian/p/5307143.html
Copyright © 2011-2022 走看看