文章40 | 阅读 14798 | 点赞0
AtomicMarkableReference和 AtomicStampedReference源码几乎相同,唯一区别就在于一个是int型的时间戳,而这个类则是布尔型的标记值。
两者区别在于AtomicStampedReference可以知道修改了多少次,而AtomicMarkableReference则只知道有没有被修改过
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
public class AtomicMarkableReference<V> {
private static class Pair<T> {
final T reference;
final boolean mark;// 布尔值
private Pair(T reference, boolean mark) {
this.reference = reference;
this.mark = mark;
}
static <T> Pair<T> of(T reference, boolean mark) {
return new Pair<T>(reference, mark);
}
}
private volatile Pair<V> pair;
private static final VarHandle PAIR;
static {
try {
MethodHandles.Lookup l = MethodHandles.lookup();
PAIR = l.findVarHandle(AtomicMarkableReference.class, "pair",
Pair.class);
} catch (ReflectiveOperationException e) {
throw new ExceptionInInitializerError(e);
}
}
private boolean casPair(Pair<V> cmp, Pair<V> val) {
return PAIR.compareAndSet(this, cmp, val);
}
/** * 创建一个带初始值和一个布尔型标记 */
public AtomicMarkableReference(V initialRef, boolean initialMark) {
pair = Pair.of(initialRef, initialMark);
}
/** * 返回当前值 */
public V getReference() {
return pair.reference;
}
/** * 返回当前标记布尔值 */
public boolean isMarked() {
return pair.mark;
}
/** * 返回当前值和当前标记布尔值 */
public V get(boolean[] markHolder) {
Pair<V> pair = this.pair;
markHolder[0] = pair.mark;
return pair.reference;
}
/** * cas更新当前值和标记值 */
public boolean weakCompareAndSet(V expectedReference,
V newReference,
boolean expectedMark,
boolean newMark) {
return compareAndSet(expectedReference, newReference,
expectedMark, newMark);
}
/** * cas更新当前值和标记值 */
public boolean compareAndSet(V expectedReference,
V newReference,
boolean expectedMark,
boolean newMark) {
Pair<V> current = pair;
return
expectedReference == current.reference &&
expectedMark == current.mark &&
((newReference == current.reference &&
newMark == current.mark) ||
casPair(current, Pair.of(newReference, newMark)));
}
/** * 无条件更新当前值和标记型布尔值 */
public void set(V newReference, boolean newMark) {
Pair<V> current = pair;
if (newReference != current.reference || newMark != current.mark)
this.pair = Pair.of(newReference, newMark);
}
/** * 获取标记型布尔值 */
public boolean attemptMark(V expectedReference, boolean newMark) {
Pair<V> current = pair;
return
expectedReference == current.reference &&
(newMark == current.mark ||
casPair(current, Pair.of(expectedReference, newMark)));
}
}
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://yumbo.blog.csdn.net/article/details/109635085
内容来源于网络,如有侵权,请联系作者删除!