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问题的更多相关文章

  1. 基于CAS分析对ABA问题的一点思考

    基于CAS分析对ABA问题的一点思考 什么是CAS? 背景 synchronized加锁消耗太大 volatile只保证可见性,不保证原子性 基础 用CPU提供的特殊指令,可以: 自动更新共享数据; ...

  2. Java 反照机制中 getMethod()和getDeclaredField()区别

    Java 反射机制中 getMethod()和getDeclaredField()区别 今天在程序中用到java反射机制时,遇到的问题记录一下:我当时遇到的问题是,我用反射getMethod()调用类 ...

  3. 解决服务器复制中SID冲突问题

    解决服务器复制中SID冲突问题 如果你有多部的主机需要安装,最快的方法是什么?想必就是用像GHOST之类的软件来进行硬盘的复制.当然,如果是安装在虚拟机之中,则需要复制虚拟的硬盘档案即可,以微软的VP ...

  4. MySQL InnoDB 日志管理机制中的MTR和日志刷盘

    1.MTR(mini-transaction) 在MySQL的 InnoDB日志管理机制中,有一个很重要的概念就是MTR.MTR是InnoDB存储擎中一个很重要的用来保证物理写的完整性和持久性的机制. ...

  5. dubbo源码分析2——SPI机制中的SPI实现类的读取和预处理

    SPI机制中的SPI实现类的读取和预处理是由ExtensionLoader类的loadFile方法来完成的 loadFile方法的作用是读取dubbo的某个SPI接口的spi描述文件,然后进行缓存,缓 ...

  6. java多线程机制中的Thread和Runnable()区别

    1.java语言使用Thread类及其子类对象来表示线程,新建的一个线程声明周期中经历 新建.(声明一个线程,此时他已经有了相应的内存空间和其他资源),运行(线程创建之久就据用了运行的条件,一旦轮到使 ...

  7. Linux内存管理机制中buffer和cache的区别

    Linux内存管理机制中buffer和cache的区别理解linux内存管理,需要深入了解linux内存的各个参数含义和规则,下面介绍一下Linux操作系统中内存buffer和cache的区别. Fr ...

  8. CAS导致的ABA问题及解决:时间戳原子引用AtomicReference、AtomicStampedReference

    1.CAS导致ABA问题: CAS算法实现一个重要前提需要取出内存中某时刻的数据并在当下时刻比较并交换,那么在这个时间差中会导致数据的变化. 比如:线程1从内存位置V中取出A,这时线程2也从V中取出A ...

  9. JUC 并发编程--05, Volatile关键字特性: 可见性, 不保证原子性,禁止指令重排, 代码证明过程. CAS了解么 , ABA怎么解决, 手写自旋锁和死锁

    问: 了解volatile关键字么? 答: 他是java 的关键字, 保证可见性, 不保证原子性, 禁止指令重排 问: 你说的这三个特性, 能写代码证明么? 答: .... 问: 听说过 CAS么 他 ...

随机推荐

  1. Adaptive AUTOSAR 学习笔记 10 - 执行管理

    本系列学习笔记基于 AUTOSAR Adaptive Platform 官方文档 R20-11 版本 AUTOSAR_EXP_PlatformDesign.pdf 缩写 EM:Execution Ma ...

  2. java try_catch 分析

    1.若一段代码前有异常抛出,并且这个异常没有被捕获,这段代码将产生编译时错误「无法访问的语句」.如 public class try_catch_Demo { public static void m ...

  3. .net core连接Liunx上MS SQL Server

    场景 由于业务要求,需要对甲方的一个在SQL Server上的财务表进行插入操作.研究了半天,因为一个小问题折腾了很久. 过程 .net core端: 1. 利用EF,就需要的导入相关的Nuget包, ...

  4. tp phpexcel 导出后台访问方法

    public function phpexcel(){ //-----excel表导出 $dataid = $_GET['dataid']; $status = $_GET['status']; $F ...

  5. Java 中节省 90% 时间的常用的工具类

    前言 你们有木有喜欢看代码的领导啊,我的领导就喜欢看我写的代码,有事没事就喜欢跟我探讨怎么写才最好,哈哈哈...挺好. 今天我们就一起来看看可以节省 90% 的加班时间的第三方开源库吧,第一个介绍的必 ...

  6. Docker未授权漏洞(2375)

    漏洞验证 直接使用浏览器访问 http://ip:2335 http://ip:2335/version http://ip:2335/info docker -H tcp://ip:2375 ver ...

  7. 被字节跳动、小米、美团面试官问的AndroidFramework难倒了? 这里有23道面试真题,助力成为offer收割机!

    目录 1.Android中多进程通信的方式有哪些?a.进程通信你用过哪些?原理是什么?(字节跳动.小米)2.描述下Binder机制原理?(东方头条)3.Binder线程池的工作过程是什么样?(东方头条 ...

  8. 安装MySQL详细说明

    安装MySQL详细说明 下载后得到zip压缩包 解压到自己的安装目录 添加环境变量 我的电脑->属性->高级->环境变量 选择PATH,在其后面添加:你的mysql安装文件下面的bi ...

  9. 前端 | Nuxt.js axios baseURL,proxy 代理

    平时用 Vue 写前端时,对于 axios 请求的常规操作一般是 统一定义好一个 axios 对象,使用 axios.defaults.baseURL 设置 baseURL 也不是不能直接把服务器地址 ...

  10. java.lang.instrument.Instrumentation

    java.lang.instrument.Instrumentation 看完文档之后,我们发现这么两个接口:redefineClasses和retransformClasses.一个是重新定义cla ...