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。 
  • 相关阅读:
    day 66 crm(3) 自创组件stark界面展示数据
    day 65 crm(2) admin源码解析,以及简单的仿造admin组件
    用 Python+nginx+django 打造在线家庭影院
    django -admin 源码解析
    day 64 crm项目(1) admin组件的初识别以及应用
    云链接 接口不允许 情况 解决方法 mysql Host is not allowed to connect to this MySQL server解决方法
    day 56 linux的安装python3 ,虚拟环境,mysql ,redis
    day55 linux 基础以及系统优化
    Codeforces 989 P循环节01构造 ABCD连通块构造 思维对云遮月参考系坐标轴转换
    Codeforces 990 调和级数路灯贪心暴力 DFS生成树两子树差调水 GCD树连通块暴力
  • 原文地址:https://www.cnblogs.com/Hermioner/p/9905284.html
Copyright © 2011-2022 走看看