AtomicStampedReference AtomicReference解决CAS机制中ABA问题
AtomicStampedReference AtomicReference解决CAS机制中ABA问题
AtomicStampedReference
AtomicStampedReference它内部不仅维护了对象值,还维护了一个版本号(可以是任何一个整数,它使用整数来表示状态值)。当AtomicStampedReference对应的数值被修改时,除了更新数据本身外,还必须要更新版本号。因此只要版本号发生变化,就能防止不恰当的写入。版本号类似于时间戳。
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicStampedReference;
public class Test {
/**
**/
public static void main(String[] args) {
AtomicInteger integer = new AtomicInteger(0);
AtomicStampedReference<Integer> reference = new AtomicStampedReference<>(100,1000);
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
integer.compareAndSet(0,1);
integer.compareAndSet(1,0);
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
boolean b = integer.compareAndSet(0, 1);
System.out.println("AtomicInteger替换");
if(b) System.out.println("0已经被替换为1");
else System.out.println("替换失败");
}
});
Thread t3 = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
reference.compareAndSet(100,-100,
reference.getStamp(), reference.getStamp()+1);
reference.compareAndSet(-100,100,
reference.getStamp(), reference.getStamp()+1);
}
});
Thread t4 = new Thread(new Runnable() {
@Override
public void run() {
int stamp = reference.getStamp();
try {
Thread.currentThread().sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
boolean b = reference.compareAndSet(100, -100,
stamp, reference.getStamp() + 1);
System.out.println("AtomicStampedReference替换");
if(b) System.out.println("100已经被替换为-100");
else System.out.println("替换失败");
}
});
t1.start();
t2.start();
t3.start();
t4.start();
}
}
输出结果:
AtomicInteger替换
0已经被替换为1
AtomicStampedReference替换
替换失败
AtomicReference
AtomicReference类提供了一个可以原子读写的对象引用变量。 原子意味着尝试更改相同AtomicReference的多个线程(例如,使用比较和交换操作)不会使AtomicReference最终达到不一致的状态。
import java.util.concurrent.atomic.AtomicReference;
public class ABAObjectTest {
public static void main(String[] args) {
SubObject subObject = new SubObject(100,"一百");
AtomicReference<SubObject> reference = new AtomicReference<>(subObject);
SubObject subObject1 = new SubObject(200,"二百");
SubObject subObject2 = new SubObject(300,"三百");
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
boolean b = reference.compareAndSet(subObject, subObject1);
SubObject object = reference.get();
System.out.println(b);
System.out.println(object);
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("=============");
System.out.println(reference.get());
boolean b = reference.compareAndSet(subObject, subObject2);
System.out.println(b);
System.out.println(reference.get());
}
});
t1.start();
t2.start();
}
}
/*输出结果:
true
SubObject{intNum=200, string='二百'}
=============
SubObject{intNum=200, string='二百'}
false
SubObject{intNum=200, string='二百'}*/
class SubObject {
public int intNum;
public String string;
public int getIntNum() {
return intNum;
}
public void setIntNum(int intNum) {
this.intNum = intNum;
}
public String getString() {
return string;
}
public void setString(String string) {
this.string = string;
}
public SubObject(int intNum, String string) {
this.intNum = intNum;
this.string = string;
}
public SubObject() {
}
@Override
public String toString() {
return "SubObject{" +
"intNum=" + intNum +
", string='" + string + '\'' +
'}';
}
}
AtomicStampedReference AtomicReference解决CAS机制中ABA问题的更多相关文章
- 基于CAS分析对ABA问题的一点思考
基于CAS分析对ABA问题的一点思考 什么是CAS? 背景 synchronized加锁消耗太大 volatile只保证可见性,不保证原子性 基础 用CPU提供的特殊指令,可以: 自动更新共享数据; ...
- Java 反照机制中 getMethod()和getDeclaredField()区别
Java 反射机制中 getMethod()和getDeclaredField()区别 今天在程序中用到java反射机制时,遇到的问题记录一下:我当时遇到的问题是,我用反射getMethod()调用类 ...
- 解决服务器复制中SID冲突问题
解决服务器复制中SID冲突问题 如果你有多部的主机需要安装,最快的方法是什么?想必就是用像GHOST之类的软件来进行硬盘的复制.当然,如果是安装在虚拟机之中,则需要复制虚拟的硬盘档案即可,以微软的VP ...
- MySQL InnoDB 日志管理机制中的MTR和日志刷盘
1.MTR(mini-transaction) 在MySQL的 InnoDB日志管理机制中,有一个很重要的概念就是MTR.MTR是InnoDB存储擎中一个很重要的用来保证物理写的完整性和持久性的机制. ...
- dubbo源码分析2——SPI机制中的SPI实现类的读取和预处理
SPI机制中的SPI实现类的读取和预处理是由ExtensionLoader类的loadFile方法来完成的 loadFile方法的作用是读取dubbo的某个SPI接口的spi描述文件,然后进行缓存,缓 ...
- java多线程机制中的Thread和Runnable()区别
1.java语言使用Thread类及其子类对象来表示线程,新建的一个线程声明周期中经历 新建.(声明一个线程,此时他已经有了相应的内存空间和其他资源),运行(线程创建之久就据用了运行的条件,一旦轮到使 ...
- Linux内存管理机制中buffer和cache的区别
Linux内存管理机制中buffer和cache的区别理解linux内存管理,需要深入了解linux内存的各个参数含义和规则,下面介绍一下Linux操作系统中内存buffer和cache的区别. Fr ...
- CAS导致的ABA问题及解决:时间戳原子引用AtomicReference、AtomicStampedReference
1.CAS导致ABA问题: CAS算法实现一个重要前提需要取出内存中某时刻的数据并在当下时刻比较并交换,那么在这个时间差中会导致数据的变化. 比如:线程1从内存位置V中取出A,这时线程2也从V中取出A ...
- JUC 并发编程--05, Volatile关键字特性: 可见性, 不保证原子性,禁止指令重排, 代码证明过程. CAS了解么 , ABA怎么解决, 手写自旋锁和死锁
问: 了解volatile关键字么? 答: 他是java 的关键字, 保证可见性, 不保证原子性, 禁止指令重排 问: 你说的这三个特性, 能写代码证明么? 答: .... 问: 听说过 CAS么 他 ...
随机推荐
- Python脚本:批量将.doc文件转化为.docx文件
将.doc转换为.docx文件有几种常用的方法: Microsoft Word 和 WPS 自带.doc转换.docx功能,但只能一个文件一个文件转换,批量转换要会员 在线网页 Office-Conv ...
- ES6 属性方法简写一例:vue methods 属性定义方法
const o = { method() { return "Hello!"; } }; // 等同于 const o = { method: function() { retur ...
- Python实用案例,Python脚本,Python实现文件自动归类
前言: 今天我们就利用Python脚本实现文件自动归类吧.直接开整~ 预备知识 这个脚本实现比较简单,我把涉及的知识点列了出来. 1.相对路径.绝对路径,绝对路径就是最完整的路径. 'D:/code/ ...
- 博主从零开始学习HTML(入门基础)
目录 从零开始学习HTML(入门基础) 互联网三大基石 HTML的Head标签中的常用元素 字体格式化标签 字符实体,以下写最常用的几个 html常用标签及解析 a标签 img标签 媒体标签audio ...
- 2020年度钻石C++C学习笔记(1)《博学谷》
1.C语言概述 1.1 什么是C语言 一提到语言这个词语,自然会想到的是像英语.汉语等这样的自然语言,因为它是人和人交换信息不可缺少的工具. 而今天计算机遍布了我们生活的每一个角落,除了人和人的相互交 ...
- postman怎么调中文
事先准备 1 安装好postman. 下载网址:https://www.postman.com/downloads/ 2 下载好app.zip中文压缩包,下载地址:https://wws.lanzou ...
- RedisTemplate连接不释放、Redis断线不重连问题、Redis连接数高飙升
使用RedisTemplate操作Redis数据,但遇到网络断线后不会重新连接 毫无头绪 一顿捣鼓 最终解决 整理如下 帮助更多的人 1.起因 使用RedisTemplate 配置 开启了事务 ena ...
- 关于表单重复提交之验证码 和谷歌Kaptcha图片验证码的使用
表单重复提交之-----验证码 表单重复提交有三种常见的情况: 一:提交完表单.服务器使用请求转来进行页面跳转.这个时候,用户按下功能键 F5,就会发起最后一次的请求. 造成表单重复提交问题.解决方法 ...
- JavaScript学习01(js概述)
JavaScript概述 JavaScript历史 要了解JavaScript,我们首先要了解一下JavaScript的诞生. 在上个世纪的1995年,当时的网景公司正凭借其Navigator浏览器成 ...
- 小知识get:利用单臂路由实现不同vlan间路由
一.单臂路由概述 1.1.单臂路由实现不同vlan间通信 链路类型 交换机连接主机的端口为access链路 交换机连接路由器的端口为Trunk链路 子接口 路由器的物理接口可以被划分成多个逻辑接口 每 ...