ABA问题_乐观锁aba引发的实际问题

ABA问题_乐观锁aba引发的实际问题ABA问题一.概述:二.什么是ABA问题?三.ABA问题的解决:原子引用:(存在ABA问题)带版本号的原子引用(解决ABA问题)一.概述:ABA问题是在多线程并发的情况下,发生的一种现象。上一次记录了有关CAS操作的一些知识,CAS通过比较内存中的一个数据是否是预期值,如果是就将它修改成新值,如果不是则进行自旋,重复比较的操作,直到某一刻内存值等于预期值再进行修改。而ABA问题则是在CAS操作中存在的一个经典问题,这个问题某些时候不会带来任何影响,某些时候却是影响很大的。二.什么是ABA问题?理解一

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

一.概述:

ABA问题是在多线程并发的情况下,发生的一种现象。上一次记录了有关CAS操作的一些知识,CAS通过比较内存中的一个数据是否是预期值,如果是就将它修改成新值,如果不是则进行自旋,重复比较的操作,直到某一刻内存值等于预期值再进行修改。而ABA问题则是在CAS操作中存在的一个经典问题,这个问题某些时候不会带来任何影响,某些时候却是影响很大的。

二.什么是ABA问题?

理解一:
当执行campare and swap会出现失败的情况。例如,一个线程先读取共享内存数据值A,随后因某种原因,线程暂时挂起,同时另一个线程临时将共享内存数据值先改为B,随后又改回为A。随后挂起线程恢复,并通过CAS比较,最终比较结果将会无变化。这样会通过检查,这就是ABA问题。 在CAS比较前会读取原始数据,随后进行原子CAS操作。这个间隙之间由于并发操作,最终可能会带来问题。
理解二
在这里插入图片描述

“ABA”问题:假设t1线程工作时间为10秒,t2线程工作时间为2秒,那么可能在A的工作期间,主内存中的共享变量 A已经被t2线程修改了多次,只是恰好最后一次修改的值是该变量的初始值,虽然用CAS判定出来的结果是期望值,但是却不是原来那个了=======》“狸猫换太子”
相当于是只关心共享变量的起始值和结束值,而不关心过程中共享变量是否被其他线程动过。
有些业务可能不需要关心中间过程,只要前后值一样就行,但是有些业务需求要求变量在中间过程不能被修改。

只靠CAS无法保证ABA问题,需要使用“原子引用”才能解决!!!!

三.ABA问题的解决:

原子引用:(存在ABA问题)

案列:

 package InterviewTest;

import java.util.concurrent.atomic.AtomicReference;

class User{ 
   
	 String name;
	 int age;
	 
	 public User(String name,int age) { 
   
		 this.name=name;
		 this.age=age;
	 }

	@Override
	public String toString() { 
   
		return "User [name=" + name + ", age=" + age + "]";
	}

	public String getName() { 
   
		return name;
	}

	public void setName(String name) { 
   
		this.name = name;
	}
	public int getAge() { 
   
		return age;
	}

	public void setAge(int age) { 
   
		this.age = age;
	}
 }
public class AtomicReferenceDemo { 
   
	public static void main(String[] args) { 
   
		User z3 = new User("z3",25);
		User li4 = new User("li4",25);
		AtomicReference<User> atomicReference  = new AtomicReference<>();
		atomicReference.set(z3);
		System.out.println(atomicReference);
		System.out.println(atomicReference.compareAndSet(z3, li4)+
							" "+atomicReference.get().toString());
		System.out.println(atomicReference.compareAndSet(li4, z3)+
				" "+atomicReference.get().toString());
	}
}

Jetbrains全家桶1年46,售后保障稳定

带版本号的原子引用(解决ABA问题)

AtomicStampedReference版本号原子引用:
案例:两种原子引用的对比


package InterviewTest;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.atomic.AtomicStampedReference;
public class ABADemo { 

static AtomicReference<Integer> atomicReference 
= new AtomicReference<>(100);
static AtomicStampedReference<Integer>  atomicStampedReference 
= new AtomicStampedReference<>(100,1);
public static void main(String[] args) { 

System.out.println("************以下是ABA问题的产生**************");
new Thread(()->{ 

atomicReference.compareAndSet(100, 101);
atomicReference.compareAndSet(101, 100);
},"t1").start();
new Thread(()->{ 

try { 

Thread.sleep(1000);
} catch (InterruptedException e) { 

e.printStackTrace();
}
System.out.println(atomicReference.compareAndSet(100, 2019)
+" "+atomicReference.get());
},"t2").start();
try { 

Thread.sleep(2000);
} catch (InterruptedException e) { 

e.printStackTrace();
}
System.out.println("************以下是ABA问题的解决**************");
new Thread(()->{ 

int stamp = atomicStampedReference.getStamp();
System.out.println(Thread.currentThread().getName()
+" "+" 第一次版本号:"+stamp);
try { 

Thread.sleep(1000);
} catch (InterruptedException e) { 

e.printStackTrace();
}
atomicStampedReference.compareAndSet(100, 
101, 
atomicStampedReference.getStamp(),
atomicStampedReference.getStamp()+1);
System.out.println(Thread.currentThread().getName()
+" "+" 第2次版本号:"+atomicStampedReference.getStamp());
atomicStampedReference.compareAndSet(101, 
100, 
atomicStampedReference.getStamp(),
atomicStampedReference.getStamp()+1);
System.out.println(Thread.currentThread().getName()
+" "+" 第3次版本号:"+atomicStampedReference.getStamp());
},"t3").start();
new Thread(()->{ 

int stamp = atomicStampedReference.getStamp();
System.out.println(Thread.currentThread().getName()
+" "+" 第一次版本号:"+stamp);
try { 

Thread.sleep(3000);
} catch (InterruptedException e) { 

e.printStackTrace();
}
boolean result =  atomicStampedReference.compareAndSet(
100, 
2019, 
stamp, 
stamp+1);
System.out.println(Thread.currentThread().getName()+
" 修改成功否:"+result+" 当前最新实际版本号:"
+atomicStampedReference.getStamp());
System.out.println(Thread.currentThread().getName()+
" 当前实际最新值:"
+atomicStampedReference.getReference());
},"t4").start();
}
}
************以下是ABA问题的产生**************
true   2019
************以下是ABA问题的解决**************
t3     第一次版本号:1
t4     第一次版本号:1
t3     第2次版本号:2
t3     第3次版本号:3
t4  修改成功否:false  当前最新实际版本号:3
t4  当前实际最新值:100
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/203708.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • linux修改文件名字_linux搜索文件名命令

    linux修改文件名字_linux搜索文件名命令在Linux环境下修改文件名可以有不同的命令方式,比如rename、mv都可以进行修改,如果用户正在了解这方面的知识,可以阅读下文了解Linux修改文件名以及批量修改文件名的方法。对于单个的文件,可以直接使用命令,那如果有大量的类似格式的文件名需要修改成其他格式的,该如何呢?比如某次测试后,保存的文件为Lan1.txt,Lan2.txt,……Lan100.txt这一百个文件需要在前面添加前缀变成…

    2022年10月24日
  • Java开发手册之应用分层「建议收藏」

    Java开发手册之应用分层「建议收藏」Java开发手册之应用分层

  • 处理Simulink的代数环的方法为逐个添加一阶惯性环节

    处理Simulink的代数环的方法为逐个添加一阶惯性环节处理Simulink的代数环的方法为逐个添加一阶惯性环节。代数环实际上是微分方程的输入在第一步没有值,而如果串联一个积分器的话就可以有初值,从而避免。通过增加一个一个时步的惯性环节,实现在基本不改变输出的情况下避免代数环。测试是可行的。…

  • matlab画图RGB调色

    matlab画图RGB调色1.使用matlab画图时,怎样才能调出顺眼的颜色呢?反正我之前使用红、绿、蓝三种颜色画图时,真的辣眼睛。下面这图是我根据一篇论文上的图像调的颜色:我也知道这并不好看,但是可以给各位提个醒、提个方向。代码也奉上:%画图%alpha是x轴的数据,result是y轴的数据,_*是实线画*形图,’Color'[0.250980.878430.81569]就是%颜色值,’MarkerFaceColor'[0.901960.901960.98039]往星形图中填充该颜色plot(alp

  • Ajaxpro组件

    Ajaxpro组件这一篇我们来看一个开源的组件:ajaxpro。虽然这是一个比较老的组件,不过实现思想和源码还是值得我们学习的。通过上一篇的介绍,我们知道要调用页面对象的方法,就是靠反射来实现的,关键是整个处理过程,包括反射调用方法、参数映射等。ajaxpro不仅在后台帮我们实现了这个过程,在前台也封装了请求调用的方法,例如ajax的相关方法,用ajaxpro的方法就可以发送异步请求了,不需要自己封装js或者使用j…

  • Spring3 MVC请求参数获取的几种方法

     一、      通过@PathVariabl获取路径中的参数  @RequestMapping(value="user/{id}/{name}",method=RequestMethod.GET) public String printMessage1(@PathVariable String id,@PathVariable String name, ModelMa…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号