AtomicIntegerFieldUpdater可以在多线程环境下安全的更新对象中的整型成员变量。
演示示例:
package com.securitit.serialize.atomics;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
public class AtomicIntegerFieldUpdaterTester {
// 创建AtomicIntegerFieldUpdater实例.
public static AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTester> updater = AtomicIntegerFieldUpdater
.newUpdater(AtomicIntegerFieldUpdaterTester.class, "counter");
// 内部计数器.
private volatile int counter = 100;
// AtomicIntegerFieldUpdater对象.
private static AtomicIntegerFieldUpdaterTester fieldUpdaterTester = new AtomicIntegerFieldUpdaterTester();
public static void main(String[] args) throws InterruptedException {
// CAS方式将counter值由100更新为200.
if (updater.compareAndSet(fieldUpdaterTester, 100, 200)) {
System.out.println("更新成功: " + fieldUpdaterTester.getCounter());
}
// CAS方式将counter值由100更新为300.
if (updater.compareAndSet(fieldUpdaterTester, 100, 300)) {
System.out.println("更新成功:" + fieldUpdaterTester.getCounter());
} else {
System.out.println("更新失败:" + fieldUpdaterTester.getCounter());
}
}
public int getCounter() {
return counter;
}
}
输出结果:
更新成功: 200
更新失败: 200
从结果来看,AtomicIntegerFieldUpdater可以正确的更新成员变量,且是通过CAS的方式更改,可以在多线程环境下使用。
源码分析:
实现基础:
AtomicIntegerFieldUpdater是一个abstract类,具体实现由AtomicIntegerFieldUpdaterImpl来完成,AtomicIntegerFieldUpdater通过模板设计模式,在自身中定义了一些主要算法。AtomicIntegerFieldUpdaterImpl依赖对象属性偏移量来完成操作。
// 对象对应属性偏移量.
private final long offset;
// 调用者类对象.
private final Class<?> cclass;
// 属性所属类对象.
private final Class<T> tclass;
方法分析:
// 普通取值.
public abstract int get(T obj);
// 普通设置值.
public abstract void set(T obj, int newValue);
// 延迟设置值.
public abstract void lazySet(T obj, int newValue);
// 依赖CAS,进行比较替换.
public abstract boolean compareAndSet(T obj, int expect, int update);
// 依赖CAS,进行比较替换.
public abstract boolean weakCompareAndSet(T obj, int expect, int update);
// 先取值,再修改.
public int getAndSet(T obj, int newValue);
// 先取值,再自增.
public int getAndIncrement(T obj);
// 先取值,在自减.
public int getAndDecrement(T obj);
// 先取值,再将原值加delta.
public int getAndAdd(T obj, int delta);
// 先自增,再取值.
public int incrementAndGet(T obj);
// 先自减,再取值.
public int decrementAndGet(T obj);
// 先将原值加delta,再取值.
public int addAndGet(T obj, int delta);
// 先取值,再修改变量的值.
public final int getAndUpdate(T obj, IntUnaryOperator updateFunction);
// 先修改变量的值,再取值.
public final int updateAndGet(T obj, IntUnaryOperator updateFunction);
// 使用IntBinaryOperator对当前值和第一个参数进行计算,并更新当前值.
public final int getAndAccumulate(T obj, int x, IntBinaryOperator accumulatorFunction);
// 使用IntBinaryOperator对当前值和第一个参数进行计算,并更新当前值.
public final int accumulateAndGet(T obj, int x, IntBinaryOperator accumulatorFunction);
AtomicIntegerFieldUpdater本身是abstract类型,是无法实例化的。AtomicIntegerFieldUpdater使用模板设计模式,预先定义了一些实现,abstract方法是需要子类去实现的具体定义。AtomicIntegerFieldUpdater内部提供了一个静态内部类实现AtomicIntegerFieldUpdaterImpl,AtomicIntegerFieldUpdaterImpl内部类首先计算指定属性的偏移位置,之后所有操作均依赖该偏移位置进行操作。
// 普通取值.
public abstract int get(T obj);
// 普通设置值.
public abstract void set(T obj, int newValue);
// 延迟设置值.
public abstract void lazySet(T obj, int newValue);
// 依赖CAS,进行比较替换.
public abstract boolean compareAndSet(T obj, int expect, int update);
// 依赖CAS,进行比较替换.
public abstract boolean weakCompareAndSet(T obj, int expect, int update);
// 先取值,再修改.
public int getAndSet(T obj, int newValue);
// 先取值,再将原值加delta.
public final int getAndAdd(T obj, int delta);
// 先取值,再自增.调用getAndAdd实现.
public int getAndIncrement(T obj);
// 先取值,在自减.调用getAndAdd实现.
public int getAndDecrement(T obj);
// 先取值,再将原值加delta.调用getAndAdd实现.
public int getAndAdd(T obj, int delta);
// 先自增,再取值.调用getAndAdd实现.
public int incrementAndGet(T obj);
// 先自减,再取值.调用getAndAdd实现.
public int decrementAndGet(T obj);
// 先将原值加delta,再取值.调用getAndAdd实现.
public int addAndGet(T obj, int delta);
AtomicIntegerFieldUpdaterImpl将父类AtomicIntegerFieldUpdater中的abstract做了实现,同时重写了父类的部分方法,
注:文中源码均来自于JDK1.8版本,不同版本间可能存在差异。
如果有哪里有不明白或不清楚的内容,欢迎留言哦!