欢迎访问昆山宝鼎软件有限公司网站! 设为首页 | 网站地图 | XML | RSS订阅 | 宝鼎邮箱 | 后台管理


新闻资讯

MENU

软件开发知识

源码实现 昆山软件开发 目前为止

点击: 次  来源:昆山软开发 时间:2017-12-19

原文出处: tomas家的小拨浪鼓

最近在看AtomicIntegerFieldUpdater的时候看到了两个很有意思的要领:compareAndSet 和 weakCompareAndSet。下面主要针对这两个要领展开接头。

基于 JDK 8

首先,我们知道AtomicIntegerFieldUpdater是一个基于反射的成果包,它可以实现针对付指定类中volatile int 字段的原子更新。

『 compareAndSet 』:

/**
 * Atomically sets the field of the given object managed by this updater
 * to the given updated value if the current value {@code ==} the
 * expected value. This method is guaranteed to be atomic with respect to
 * other calls to {@code compareAndSet} and {@code set}, but not
 * necessarily with respect to other changes in the field.
 *
 * @param obj An object whose field to conditionally set
 * @param expect the expected value
 * @param update the new value
 * @return {@code true} if successful
 * @throws ClassCastException if {@code obj} is not an instance
 * of the class possessing the field established in the constructor
 */
public abstract boolean compareAndSet(T obj, int expect, int update);

以原子的方法更新这个更新器所打点的工具(obj)的成员变量,而且将这个成员变量更新为给定的更新后的值(update)假如当前值便是期望值(expect)时。

当存在其他利用‘compareAndSet’可能’set’的环境下,这个要领可以确保是原子的,但假如你用其他的方法去改变这个成员变量时(如,利用直接赋值的方法 field=newField),那么它是不会遵循这个原子性的。

嗯,这个要领好领略,compareAndSet担保了:a) 只有field的值为expect时;b) 将field的值修改为update的值;这两步是原子完成的。同时field必然为一个volatile属性,而volatile担保了属性在线程间的可见性,昆山软件开发,以及防备了指令的重排序。(关于volatile下面还会进一步展开)。嗯,一切看起来都挺优美的。

然后,我们来看下另一个要领『weakCompareAndSet』:

/**
 * Atomically sets the field of the given object managed by this updater
 * to the given updated value if the current value {@code ==} the
 * expected value. This method is guaranteed to be atomic with respect to
 * other calls to {@code compareAndSet} and {@code set}, but not
 * necessarily with respect to other changes in the field.
 *
 * <p><a href="package-summary.html#weakCompareAndSet">May fail
 * spuriously and does not provide ordering guarantees</a>, so is
 * only rarely an appropriate alternative to {@code compareAndSet}.
 *
 * @param obj An object whose field to conditionally set
 * @param expect the expected value
 * @param update the new value
 * @return {@code true} if successful
 * @throws ClassCastException if {@code obj} is not an instance
 * of the class possessing the field established in the constructor
 */
public abstract boolean weakCompareAndSet(T obj, int expect, int update);

以原子的方法更新这个更新器所打点的工具(obj)的成员变量,而且将这个成员变量更新为给定的更新后的值(update)假如当前值便是期望值(expect)时。

当存在其他利用‘compareAndSet’可能’set’的环境下,这个要领可以确保是原子的,但假如你用其他的方法去改变这个成员变量时(如,利用直接赋值的方法 field=newField),那么它是不会遵循这个原子性的。

该要领大概大概虚假的失败而且不会提供一个排序的担保,所以它在少少的环境下用于取代compareAndSet要领。

第一次看weakCompareAndSet doc文档的说明时,我是狐疑的。我并不清楚你说的“fail spuriously”和“not provide ordering guarantees”简直切寄义。于是我查询了些相关资料。

首先,我从jdk 8 的官方文档的java.util.concurrent.atomic上找到这么二段话:

The atomic classes also support method weakCompareAndSet, which has limited applicability. On some platforms, the weak version may be more efficient than compareAndSet in the normal case, but differs in that any given invocation of the weakCompareAndSet method may return false spuriously (that is, for no apparent reason). A false return means only that the operation may be retried if desired, relying on the guarantee that repeated invocation when the variable holds expectedValue and no other thread is also attempting to set the variable will eventually succeed. (Such spurious failures may for example be due to memory contention effects that are unrelated to whether the expected and current values are equal.) Additionally weakCompareAndSet does not provide ordering guarantees that are usually needed for synchronization control. However, the method may be useful for updating counters and statistics when such updates are unrelated to the other happens-before orderings of a program. When a thread sees an update to an atomic variable caused by a weakCompareAndSet, it does not necessarily see updates to any other variables that occurred before the weakCompareAndSet. This may be acceptable when, for example, updating performance statistics, but rarely otherwise.