1.原子类
java.util.concurrent.atomic包下有很多原子类,这些原子类扩展了volatile的概念,使用这些原子类我们可以对变量进行原子的更新。
2.AtomicBoolean
/**
* Atomically sets the value to the given updated value
* if the current value {@code ==} the expected value.
*
* @param expect the expected value
* @param update the new value
* @return {@code true} if successful. False return indicates that
* the actual value was not equal to the expected value.
*/
public final boolean compareAndSet(boolean expect, boolean update) {
int e = expect ?1 :0;
int u = update ?1 :0;
return unsafe.compareAndSwapInt(this, valueOffset, e, u);
}
compareAndSet方法使用Unsafe类的compareAndSwapInt进行变量的更新,这个类的方法基本都是native方法,由C++操作底层硬件进行变量的更新(原子方式)。compareAndSwapInt第一个参数为对象实例,第二个参数为要修改变量的地址空间的offset,第三个参数为期望的变量的值,第四个参数为更新后的变量值。
/**
* Atomically sets to the given value and returns the previous value.
*
* @param newValue the new value
* @return the previous value
*/
public final boolean getAndSet(boolean newValue) {
boolean prev;
do {
prev = get();
} while (!compareAndSet(prev, newValue));
return prev;
}
getAndSet对value域进行原子更新,首先获取value的原值,使用compareAndSet进行更新操作,当prev因为竞争在更新的过程中被修改了,方法会返回false,导致do while一直执行,直到prev的值符合预期(在本次设置过程中没有被修改为其他值),原子方式更新成功。
/**
* Eventually sets to the given value.
*
* @param newValue the new value
* @since 1.6
*/
public final void lazySet(boolean newValue) {
int v = newValue ?1 :0;
unsafe.putOrderedInt(this, valueOffset, v);
}
lazySet方法会将value的值最终设置为newValue,可以看到unsafe类使用的更新方法中没有期望值这个参数。putOrderedInt的作用为禁止指令重排,关于指令重排的介绍参照https://www.cnblogs.com/chenyangyao/p/5269622.html。
网友评论