AtomicStampedReference 源码分析
AtomicStampedReference
AtomicStampedReference 能解决什么问题?什么时候使用 AtomicStampedReference?
1)AtomicStampedReference 维护带有整数标识的对象引用,可以用原子方式对其进行更新。
2)AtomicStampedReference 能够解决 CAS 的 ABA 问题。
如何使用 AtomicStampedReference?
1)使用 AtomicStampedReference 解决无锁 CAS 过程中的 ABA 问题,特别是涉及资金时。
使用 AtomicStampedReference 有什么风险?
1)高并发场景下,自旋 CAS 长时间失败会导致 CPU 飙升
AtomicStampedReference 核心操作的实现原理?
创建实例
private static class Pair<T> {
/**
* 目标对象引用
*/
final T reference;
/**
* 整形标记
*/
final int stamp;
private Pair(T reference, int stamp) {
this.reference = reference;
this.stamp = stamp;
}
static <T> Pair<T> of(T reference, int stamp) {
return new Pair<>(reference, stamp);
}
}
private volatile Pair<V> pair;
/**
* 创建具有给定对象引用和标识值的新 AtomicStampedReference 实例
*/
public AtomicStampedReference(V initialRef, int initialStamp) {
pair = Pair.of(initialRef, initialStamp);
}
尝试原子更新
/**
* 如果旧引用==expectedReference && 旧整形标记==expectedStamp,
* 则尝试原子更新引用为 newReference,时间标记为 newStamp
*/
public boolean compareAndSet(V expectedReference,
V newReference,
int expectedStamp,
int newStamp) {
final Pair<V> current = pair;
return
expectedReference == current.reference &&
expectedStamp == current.stamp &&
(newReference == current.reference &&
newStamp == current.stamp ||
casPair(current, Pair.of(newReference, newStamp)));
}
读取值
/**
* 读取引用值
*/
public V getReference() {
return pair.reference;
}
/**
* 读取整形标记
*/
public int getStamp() {
return pair.stamp;
}
/**
* 读取引用值,并将整形标记存储到形参数组索引为 0 的位置
*/
public V get(int[] stampHolder) {
final Pair<V> pair = this.pair;
stampHolder[0] = pair.stamp;
return pair.reference;
}
写入值
/**
* 无条件地更新引用值和时间标记
*/
public void set(V newReference, int newStamp) {
final Pair<V> current = pair;
if (newReference != current.reference || newStamp != current.stamp) {
this.pair = Pair.of(newReference, newStamp);
}
}
原子更新值,并发更新时可能失败
/**
* 如果旧引用==expectedReference && 旧整形标记==expectedStamp,
* 则尝试原子更新引用为 newReference,时间标记为 newStamp
*/
public boolean weakCompareAndSet(V expectedReference,
V newReference,
int expectedStamp,
int newStamp) {
return compareAndSet(expectedReference, newReference,
expectedStamp, newStamp);
}
/**
* 如果旧引用==expectedReference && 旧整形标记==expectedStamp,
* 则尝试原子更新引用为 newReference,时间标记为 newStamp
*/
public boolean compareAndSet(V expectedReference,
V newReference,
int expectedStamp,
int newStamp) {
final Pair<V> current = pair;
return
expectedReference == current.reference &&
expectedStamp == current.stamp &&
(newReference == current.reference &&
newStamp == current.stamp ||
casPair(current, Pair.of(newReference, newStamp)));
}
private static final VarHandle PAIR;
static {
try {
final MethodHandles.Lookup l = MethodHandles.lookup();
PAIR = l.findVarHandle(AtomicStampedReference.class, "pair",
Pair.class);
} catch (final ReflectiveOperationException e) {
throw new Error(e);
}
}
private boolean casPair(Pair<V> cmp, Pair<V> val) {
return AtomicStampedReference.PAIR.compareAndSet(this, cmp, val);
}
AtomicStampedReference 源码分析的更多相关文章
- 死磕 java并发包之AtomicStampedReference源码分析(ABA问题详解)
问题 (1)什么是ABA? (2)ABA的危害? (3)ABA的解决方法? (4)AtomicStampedReference是什么? (5)AtomicStampedReference是怎么解决AB ...
- AtomicStampedReference源码分析
public class Snippet { //修改的是AtomicStampedReference对象里面的值了. public static void main(String[] args) { ...
- AtomicInteger源码分析——基于CAS的乐观锁实现
AtomicInteger源码分析——基于CAS的乐观锁实现 1. 悲观锁与乐观锁 我们都知道,cpu是时分复用的,也就是把cpu的时间片,分配给不同的thread/process轮流执行,时间片与时 ...
- Java高并发之无锁与Atomic源码分析
目录 CAS原理 AtomicInteger Unsafe AtomicReference AtomicStampedReference AtomicIntegerArray AtomicIntege ...
- 并发-AtomicInteger源码分析—基于CAS的乐观锁实现
AtomicInteger源码分析—基于CAS的乐观锁实现 参考: http://www.importnew.com/22078.html https://www.cnblogs.com/mantu/ ...
- ABP源码分析一:整体项目结构及目录
ABP是一套非常优秀的web应用程序架构,适合用来搭建集中式架构的web应用程序. 整个Abp的Infrastructure是以Abp这个package为核心模块(core)+15个模块(module ...
- HashMap与TreeMap源码分析
1. 引言 在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Ja ...
- nginx源码分析之网络初始化
nginx作为一个高性能的HTTP服务器,网络的处理是其核心,了解网络的初始化有助于加深对nginx网络处理的了解,本文主要通过nginx的源代码来分析其网络初始化. 从配置文件中读取初始化信息 与网 ...
- zookeeper源码分析之五服务端(集群leader)处理请求流程
leader的实现类为LeaderZooKeeperServer,它间接继承自标准ZookeeperServer.它规定了请求到达leader时需要经历的路径: PrepRequestProcesso ...
随机推荐
- 对于出现拒绝访问root用户的解决方案
提示:ERROR 1044 (42000): Access denied for user ''@'localhost' to database 'mysql' 由于使用mysql -u root ...
- django后台集成富文本编辑器Tinymce的使用
富文本编辑器Tinymce是使用步骤: 1.首先去python的模块包的网站下载一个django-tinymce的包 2.下载上图的安装包,然后解压,进入文件夹,执行: (pychrm直接运行命令pi ...
- django前端分页小组件
# -*- coding:utf-8 -*- from django.utils.safestring import mark_safe class Page(object): def __init_ ...
- Views的补充
views的补充 请求头一般与请求内容用/r/n/r/n隔开 请求头包含的内容 request.Meta(...) 一般在下面几种方法里面取不到的东西需要去原生的头里面去取,比如用户的终端类型 req ...
- C#配合大数据开发,nest.dll的使用
一,添加Nest.dll引用 结果如下多了如下DLL: Elasticsearch.Net.dll,Nest.dll 二,上代码: using Common.EsModel; using Elasti ...
- vuex实现数据共享
1.store.js结构 import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Sto ...
- Zabbix--02 自定义监控主机
目录 一. Zabbix 监控基础架构 二. zabbix 快速监控主机 1.安装zabbix-agent 2.配置zabbix-agent 3.启动zabbix-agent并检查 4.zabbix- ...
- HBase(二)——搭建Standalone HBase
HBase搭建--Standalone HBase 1.搭建方式说明 the setup of a single-node standalone HBase. A standalone instanc ...
- [易学易懂系列|golang语言|零基础|快速入门|(一)]
golang编程语言,是google推出的一门语言. 主要应用在系统编程和高性能服务器编程,有广大的市场前景,目前整个生态也越来越强大,未来可能在企业应用和人工智能等领域占有越来越重要的地位. 本文章 ...
- php内置函数分析之strpos()
PHP_FUNCTION(strpos) { zval *needle; zend_string *haystack; char *found = NULL; ]; zend_long offset ...