[超级链接:Java并发学习系列-绪论]
[系列概述: Java并发22:Atomic系列-原子类型整体概述与类别划分]
本章主要对原子类型字段更新器进行学习。
在java.util.concurrent.atomic中,原子类型字段更新器有以下三种:
原子类型字段更新器在内部通过Unsafe类的native方法保证操作的原子性。
关于原子类型字段更新器的使用需要注意一下几个方面:
首先学习上述三种原子类型字段更新器的通用方法,这些方法如下:
原子类型字段更新器的通用方法与普通原子类型的通用方法类似,唯一的区别在于多了一个参数:obj(被修改的字段的所属对象)。
场景说明:
实例代码:
自定义类型MyVolatileType:
/**
* 自定义数组,用于字段更新器演示
*
* @author hanchao 2018/3/20 22:35
**/
static class MyVolatileType {
//自定义-键
//必须是volatile;必须是long,不能是Long
//用AtomicLongFieldUpdater处理
//如果是Long的,则用AtomicReferenceFieldUpdater
private volatile int index;
//newUpdater(Class对象,字段名)
//字段更新器需要与字段的访问类型一致
private static final AtomicIntegerFieldUpdater integerFieldUpdater =
AtomicIntegerFieldUpdater.newUpdater(MyVolatileType.class, "index");
//自定义-值
//必须是volatile
//需用AtomicReferenceFieldUpdater处理
private volatile String value;
//newUpdater(Class对象,字段名)
//字段更新器需要与字段的访问类型一致
private static final AtomicLongFieldUpdater longFieldUpdater = AtomicLongFieldUpdater.newUpdater(MyVolatileType.class, "time");
//自定义-创建时间
//必须是volatile;必须是int,不能是Integer
//用AtomicIntegerFieldUpdater处理
//如果是Integer的,则用AtomicReferenceFieldUpdater
private volatile long time;
//newUpdater(Class对象,字段Class对象,字段名)
//字段更新器需要与字段的访问类型一致
private static final AtomicReferenceFieldUpdater referenceFieldUpdater =
AtomicReferenceFieldUpdater.newUpdater(MyVolatileType.class, String.class, "value");
@Override
public String toString() {
return "MyVolatileType{" +
"index=" + index +
", value='" + value + '\'' +
", time=" + time +
'}';
}
public MyVolatileType(int index, String value, long time) {
this.index = index;
this.value = value;
this.time = time;
}
}
字段更新器-通用方法演示:
/**
* 字段更新器-通用方法演示-以AtomicReferenceFieldUpdater为例
*
* @author hanchao 2018/3/20 22:50
**/
public void fieldUpdaterCommonMethodDemo() {
LOGGER.info("=======字段更新器-通用方法演示-以AtomicReferenceFieldUpdater为例");
//get(obj)
LOGGER.info("get(obj):获取值----初始值:" + referenceFieldUpdater.get(this));
//set(obj,newValue)
referenceFieldUpdater.set(this, "New Day!");
LOGGER.info("set(obj,newValue):设置值---" + referenceFieldUpdater.get(this));
//lazySet(obj,newValue)
referenceFieldUpdater.lazySet(this, "Lazy Day!");
LOGGER.info("lazySet(obj,newValue):设置值(无可见性)---" + referenceFieldUpdater.get(this));
//getAndSet(obj,newValue)
LOGGER.info("getAndSet(obj,newValue):赋值,并返回旧值:" + referenceFieldUpdater.getAndSet(this, "Good Day!"));
//compareAndSet(obj,expect,newValue)
LOGGER.info("compareAndSet(obj,expect,newValue):如果是期望的值,则赋值,并返回赋值结果:"
+ referenceFieldUpdater.compareAndSet(this, "Good Day!", "Good good Day!")
+ ",---" + referenceFieldUpdater.get(this) + "\n");
}
测试代码:
MyVolatileType myArray = new MyVolatileType(1, "David", System.currentTimeMillis());
LOGGER.info("原始值:" + myArray.toString() + "\n");
//字段更新器的通用方法
myArray.fieldUpdaterCommonMethodDemo();
LOGGER.info("当前值:" + myArray.toString() + "\n");
运行结果:
2018-03-25 16:43:43 INFO AtomicFieldUpdater:121 - 原始值:MyVolatileType{index=1, value='David', time=1521967423424}
2018-03-25 16:43:43 INFO AtomicFieldUpdater:56 - =======字段更新器-通用方法演示-以AtomicReferenceFieldUpdater为例
2018-03-25 16:43:43 INFO AtomicFieldUpdater:58 - get(obj):获取值----初始值:David
2018-03-25 16:43:43 INFO AtomicFieldUpdater:61 - set(obj,newValue):设置值---New Day!
2018-03-25 16:43:43 INFO AtomicFieldUpdater:64 - lazySet(obj,newValue):设置值(无可见性)---Lazy Day!
2018-03-25 16:43:43 INFO AtomicFieldUpdater:66 - getAndSet(obj,newValue):赋值,并返回旧值:Lazy Day!
2018-03-25 16:43:43 INFO AtomicFieldUpdater:68 - compareAndSet(obj,expect,newValue):如果是期望的值,则赋值,并返回赋值结果:true,---Good good Day!
2018-03-25 16:43:43 INFO AtomicFieldUpdater:124 - 当前值:MyVolatileType{index=1, value='Good good Day!', time=1521967423424}
然后学习AtomicIntegerFieldUpdater和AtomicLongFieldUpdater独有的一些方法,这些方法如下:
i ++
,具有原子性和可见性。++ i
,具有原子性和可见性。i --
,具有原子性和可见性。-- i
,具有原子性和可见性。AtomicIntegerFieldUpdater和AtomicLongFieldUpdater的独有方法与AtomicInteger和AtomicLong的独有方法类似,唯一的区别在于多了一个参数:obj(被修改的字段的所属对象)。
实例代码:
字段更新器-int/long特殊方法演示:
/**
* 字段更新器-int/long特殊方法演示
*
* @author hanchao 2018/3/20 22:59
**/
public void fieldUpdaterSpecialMethodDemo() {
LOGGER.info("=======字段更新器-int/long特殊方法演示");
//getAndAdd(obj,delta)和addAndGet(obj,delta)
LOGGER.info("index=" + integerFieldUpdater.getAndIncrement(this) + ",time=" + longFieldUpdater.get(this));
LOGGER.info("getAndAdd(obj,delta):增量计算,并返回旧值index:" + integerFieldUpdater.getAndAdd(this, 2)
+ ",new = " + integerFieldUpdater.get(this));
LOGGER.info("addAndGet(obj,delta):增量计算,并返回新值time:" + longFieldUpdater.addAndGet(this, System.currentTimeMillis())
+ ",new = " + longFieldUpdater.get(this));
//getAndIncrement(obj)和incrementAndGet(obj)
LOGGER.info("getAndIncrement(obj):自增,并返回旧值index:" + integerFieldUpdater.getAndIncrement(this)
+ ",new = " + integerFieldUpdater.get(this));
LOGGER.info("incrementAndGet(obj):自增,并返回新值time:" + longFieldUpdater.incrementAndGet(this)
+ ",new = " + longFieldUpdater.get(this));
//getAndDecrement(obj)和decrementAndGet(ojb)
LOGGER.info("getAndDecrement(obj):自减,并返回旧值index:" + integerFieldUpdater.getAndDecrement(this)
+ ",new = " + integerFieldUpdater.get(this));
LOGGER.info("decrementAndGet(obj):自减,并返回新值time:" + longFieldUpdater.decrementAndGet(this)
+ ",new = " + longFieldUpdater.get(this) + "\n");
}
测试代码:
MyVolatileType myArray = new MyVolatileType(1, "David", System.currentTimeMillis());
LOGGER.info("原始值:" + myArray.toString() + "\n");
myArray.fieldUpdaterSpecialMethodDemo();
LOGGER.info("当前值:" + myArray.toString() + "\n");
运行结果:
2018-03-25 17:29:50 INFO AtomicFieldUpdater:121 - 原始值:MyVolatileType{index=1, value='David', time=1521970190687}
2018-03-25 17:29:50 INFO AtomicFieldUpdater:79 - =======字段更新器-int/long特殊方法演示
2018-03-25 17:29:50 INFO AtomicFieldUpdater:81 - index=1,time=1521970190687
2018-03-25 17:29:50 INFO AtomicFieldUpdater:82 - getAndAdd(obj,delta):增量计算,并返回旧值index:2,new = 4
2018-03-25 17:29:50 INFO AtomicFieldUpdater:84 - addAndGet(obj,delta):增量计算,并返回新值time:3043940381384,new = 3043940381384
2018-03-25 17:29:50 INFO AtomicFieldUpdater:87 - getAndIncrement(obj):自增,并返回旧值index:4,new = 5
2018-03-25 17:29:50 INFO AtomicFieldUpdater:89 - incrementAndGet(obj):自增,并返回新值time:3043940381385,new = 3043940381385
2018-03-25 17:29:50 INFO AtomicFieldUpdater:92 - getAndDecrement(obj):自减,并返回旧值index:5,new = 4
2018-03-25 17:29:50 INFO AtomicFieldUpdater:94 - decrementAndGet(obj):自减,并返回新值time:3043940381384,new = 3043940381384
2018-03-25 17:29:50 INFO AtomicFieldUpdater:127 - 当前值:MyVolatileType{index=4, value='David', time=3043940381384}