当前位置: 首页 > news >正文

个人主页建站/百度今日小说排行榜

个人主页建站,百度今日小说排行榜,网络品牌推广策划方案,个人博客网站教程本文主要研究的是关于Java中ABA问题及避免的相关内容,具体如下。在《Java并发实战》一书的第15章中有一个用原子变量实现的并发栈,代码如下:public class Node {public final String item;public Node next;public Node(String item){this.it…

本文主要研究的是关于Java中ABA问题及避免的相关内容,具体如下。

在《Java并发实战》一书的第15章中有一个用原子变量实现的并发栈,代码如下:

public class Node {

public final String item;

public Node next;

public Node(String item){

this.item = item;

}

}

public class ConcurrentStack {

AtomicReference top = new AtomicReference();

public void push(String item){

Node newTop = new Node(item);

Node oldTop;

do{

oldTop = top.get();

newTop.next = oldTop;

}

while(!top.compareAndSet(oldTop, newTop));

}

public String pop(){

Node newTop;

Node oldTop;

do{

oldTop = top.get();

if(oldTop == null){

return null;

}

newTop = oldTop.next;

}

while(!top.compareAndSet(oldTop, newTop));

return oldTop.item;

}

}

这个例子并不会引发ABA问题,至于为什么不会,后面再讲解,下面先讲一下ABA问题

什么是ABA?

引用原书的话:如果在算法中的节点可以被循环使用,那么在使用“比较并交换”指令就可能出现这种问题,在CAS操作中将判断“V的值是否仍然为A?”,并且如果是的话就继续执行更新操作,在某些算法中,如果V的值首先由A变为B,再由B变为A,那么CAS将会操作成功

ABA的例子

有时候,ABA造成的后果很严重,下面将并发栈的例子修改一下,看看ABA会造成什么问题:

public class Node {

public final String item;

public Node next;

public Node(String item){

this.item = item;

}

}

public class ConcurrentStack {

AtomicReference top = new AtomicReference();

public void push(Node node){

Node oldTop;

do{

oldTop = top.get();

node.next = oldTop;

}

while(!top.compareAndSet(oldTop, node));

}

public Node pop(int time){

Node newTop;

Node oldTop;

do{

oldTop = top.get();

if(oldTop == null){

return null;

}

newTop = oldTop.next;

TimeUnit.SECONDS.sleep(time);

}

while(!top.compareAndSet(oldTop, newTop));

return oldTop;

}

}

注意这里的变化,Node基本没有变化

重点关注ConcurrentStack的变化

1、push方法:原来是使用内容构造Node,现在直接传入Node,这样就符合了“在算法中的节点可以被循环使用”这个要求

2、pop方法的sleep,这是模拟线程的执行情况,以便观察结果

我们先往stack中压入两个Node:

ConcurrentStack stack = new ConcurrentStack();

stack.push(new Node("A"));

stack.push(new Node("B"));

然后创建两个线程来执行出入栈的操作

线程A先执行出栈:让NodeA出栈

stack.pop(3);

因为某些原因,线程A执行出栈比较久,用了3s

线程B执行出栈之后再入栈:先然NodeA和NodeB出栈,然后让NodeD,NodeC,NodeA入栈(NodeA在栈顶)

Node A = stack.pop(0);

stack.pop(0);

stack.push(new Node("D"));

stack.push(new Node("C"));

stack.push(A);

注意:线程B实现了节点的循环利用,它先将栈里面的内容全部出栈,然后入栈,最后栈顶的内容是之前出栈的Node

线程B执行完这些动作之后,线程A才执行CAS,此时CAS是可以执行成功的

按照原来的想法,线程A和B执行之后,stack的内容应该是:C和D,C在栈顶,但这里的执行结果却是Stack中什么都没有,这就是ABA问题

如何避免ABA问题

Java中提供了AtomicStampedReference和AtomicMarkableReference来解决ABA问题

AtomicStampedReference可以原子更新两个值:引用和版本号,通过版本号来区别节点的循环使用,下面看AtomicStampedReference的例子:

public class ConcurrentStack {

AtomicStampedReference top = new AtomicStampedReference(null,0);

public void push(Node node){

Node oldTop;

int v;

do{

v=top.getStamp();

oldTop = top.getReference();

node.next = oldTop;

}

while(!top.compareAndSet(oldTop, node,v,v+1));

// }while(!top.compareAndSet(oldTop, node,top.getStamp(),top.getStamp()+1));

}

public Node pop(int time){

Node newTop;

Node oldTop;

int v;

do{

v=top.getStamp();

oldTop = top.getReference();

if(oldTop == null){

return null;

}

newTop = oldTop.next;

try {

TimeUnit.SECONDS.sleep(time);

}

catch (InterruptedException e) {

e.printStackTrace();

}

}

while(!top.compareAndSet(oldTop, newTop,v,v+1));

// }while(!top.compareAndSet(oldTop, newTop,top.getStamp(),top.getStamp()));

return oldTop;

}

public void get(){

Node node = top.getReference();

while(node!=null){

System.out.println(node.getItem());

node = node.getNode();

}

}

}

注意:不能使用注释中的方式,否则就和单纯使用原子变量没有区别了

AtomicMarkableReference可以原子更新一个布尔类型的标记位和引用类型,看下面的例子:

AtomicMarkableReference top = new AtomicMarkableReference(null,true);

public void push(Node node){

Node oldTop;

Boolean v;

do{

v=top.isMarked();

oldTop = top.getReference();

node.next = oldTop;

}

while(!top.compareAndSet(oldTop, node,v,!v));

}

总结

以上就是本文关于浅谈Java中ABA问题及避免的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

http://www.lbrq.cn/news/1051687.html

相关文章:

  • 网站审核时间/搜索引擎优化的例子
  • 顺德网站开发招聘/无锡网站制作
  • html5转wordpress主题/seo标题优化裤子关键词
  • 在婚恋网站上做红娘怎么样/不受国内限制的浏览器下载
  • 聊城做网站的公司平台/快速建站平台
  • 网站花瓣飘落的效果怎么做/安徽网站推广优化
  • vue做网站/seo如何优化关键词
  • 温州建设小学网站首页/东莞今天新增加的情况
  • 网站开发图片存哪里/seo关键词优化平台
  • 怎样维护网站建设/目前最新的营销方式有哪些
  • 还有多少用.net做网站的/成都seo培训班
  • 郑州手机网站制作/app001推广平台官网
  • 中建材建设有限公司网站/上海企业优化
  • 重庆南岸营销型网站建设公司哪家专业/sem推广竞价
  • 广西贵港建设集团有限公司网站/艾滋病阻断药有哪些
  • 做网站需要的带宽上行还是下行/培训机构是干什么的
  • 一元购网站建设流程图/推广普通话手抄报简单
  • 静态网页素材/seo网站优化排名
  • 漳州网站建设优化/淮北seo排名
  • 做网站网站如何定位/app下载注册量推广平台
  • 长沙网站模板建设/一键识图找原图
  • 快速开发手机网站/微商引流的最快方法是什么
  • 买网站去哪买/关键词挖掘方法
  • 做秩序册的网站/附近的成人电脑培训班
  • 不建网站如何做淘宝客/无锡网站制作
  • 博网站建设/抖音自动推广引流app
  • 网站建设优化服务方案/百度下载并安装最新版
  • 做地方服务性网站/今年疫情最新消息
  • 扬州 网站 建设/企业网站类型有哪些
  • wordpress 主题编写/网站优化是什么
  • 如何理解SA_RESTART”被信号中断的系统调用自动重启“?
  • 【Redis7.x】docker配置主从+sentinel监控遇到的问题与解决
  • Java异常:认识异常、异常的作用、自定义异常
  • 基于LLM的Chat应用测试方法探索:系统化评估与持续优化
  • HTTP 请求返回状态码和具体含义?200、400、403、404、502、503、504等
  • HarmonyOS SDK助力讯飞听见App能力建设