最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談Java中ABA問(wèn)題及避免

 更新時(shí)間:2018年01月16日 11:02:45   作者:li954644351  
這篇文章主要介紹了淺談Java中ABA問(wèn)題及避免,具有一定借鑒價(jià)值,需要的朋友可以參考下

本文主要研究的是關(guān)于Java中ABA問(wèn)題及避免的相關(guān)內(nèi)容,具體如下。

在《Java并發(fā)實(shí)戰(zhàn)》一書(shū)的第15章中有一個(gè)用原子變量實(shí)現(xiàn)的并發(fā)棧,代碼如下:

public class Node {
	public final String item;
	public Node next;
	public Node(String item){
		this.item = item;
	}
}
public class ConcurrentStack {
	AtomicReference<Node> top = new AtomicReference<Node>();
	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;
	}
}

這個(gè)例子并不會(huì)引發(fā)ABA問(wèn)題,至于為什么不會(huì),后面再講解,下面先講一下ABA問(wèn)題

什么是ABA?

引用原書(shū)的話(huà):如果在算法中的節(jié)點(diǎn)可以被循環(huán)使用,那么在使用“比較并交換”指令就可能出現(xiàn)這種問(wèn)題,在CAS操作中將判斷“V的值是否仍然為A?”,并且如果是的話(huà)就繼續(xù)執(zhí)行更新操作,在某些算法中,如果V的值首先由A變?yōu)锽,再由B變?yōu)锳,那么CAS將會(huì)操作成功

ABA的例子

有時(shí)候,ABA造成的后果很?chē)?yán)重,下面將并發(fā)棧的例子修改一下,看看ABA會(huì)造成什么問(wèn)題:

public class Node {
	public final String item;
	public Node next;
	public Node(String item){
		this.item = item;
	}
}
public class ConcurrentStack {
	AtomicReference<Node> top = new AtomicReference<Node>();
	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基本沒(méi)有變化

重點(diǎn)關(guān)注ConcurrentStack的變化

1、push方法:原來(lái)是使用內(nèi)容構(gòu)造Node,現(xiàn)在直接傳入Node,這樣就符合了“在算法中的節(jié)點(diǎn)可以被循環(huán)使用”這個(gè)要求

2、pop方法的sleep,這是模擬線(xiàn)程的執(zhí)行情況,以便觀察結(jié)果

我們先往stack中壓入兩個(gè)Node:

ConcurrentStack stack = new ConcurrentStack(); 
stack.push(new Node("A")); 
stack.push(new Node("B")); 

然后創(chuàng)建兩個(gè)線(xiàn)程來(lái)執(zhí)行出入棧的操作

線(xiàn)程A先執(zhí)行出棧:讓NodeA出棧

stack.pop(3); 

因?yàn)槟承┰?,線(xiàn)程A執(zhí)行出棧比較久,用了3s

線(xiàn)程B執(zhí)行出棧之后再入棧:先然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); 

注意:線(xiàn)程B實(shí)現(xiàn)了節(jié)點(diǎn)的循環(huán)利用,它先將棧里面的內(nèi)容全部出棧,然后入棧,最后棧頂?shù)膬?nèi)容是之前出棧的Node

線(xiàn)程B執(zhí)行完這些動(dòng)作之后,線(xiàn)程A才執(zhí)行CAS,此時(shí)CAS是可以執(zhí)行成功的

按照原來(lái)的想法,線(xiàn)程A和B執(zhí)行之后,stack的內(nèi)容應(yīng)該是:C和D,C在棧頂,但這里的執(zhí)行結(jié)果卻是Stack中什么都沒(méi)有,這就是ABA問(wèn)題

如何避免ABA問(wèn)題

Java中提供了AtomicStampedReference和AtomicMarkableReference來(lái)解決ABA問(wèn)題

AtomicStampedReference可以原子更新兩個(gè)值:引用和版本號(hào),通過(guò)版本號(hào)來(lái)區(qū)別節(jié)點(diǎn)的循環(huán)使用,下面看AtomicStampedReference的例子:

public class ConcurrentStack {
	AtomicStampedReference<Node> top = new AtomicStampedReference<Node>(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();
		}
	}
}

注意:不能使用注釋中的方式,否則就和單純使用原子變量沒(méi)有區(qū)別了

AtomicMarkableReference可以原子更新一個(gè)布爾類(lèi)型的標(biāo)記位和引用類(lèi)型,看下面的例子:

AtomicMarkableReference<Node> top = new AtomicMarkableReference<Node>(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));
}

總結(jié)

以上就是本文關(guān)于淺談Java中ABA問(wèn)題及避免的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關(guān)專(zhuān)題,如有不足之處,歡迎留言指出。感謝朋友們對(duì)本站的支持!

相關(guān)文章

  • JavaSE、JavaEE和JavaWeb三大工程目錄詳解

    JavaSE、JavaEE和JavaWeb三大工程目錄詳解

    這篇文章主要給大家介紹了關(guān)于JavaSE、JavaEE和JavaWeb三大工程目錄的相關(guān)資料,很多對(duì)java不是很了解的同學(xué)在看到課程?綱的時(shí)候發(fā)現(xiàn)??出現(xiàn)了JavaSE、JavaEE、JavaME、JavaWEB這些詞,搞得?頭霧?,需要的朋友可以參考下
    2023-07-07
  • Java Apache Shiro安全框架快速開(kāi)發(fā)詳解流程

    Java Apache Shiro安全框架快速開(kāi)發(fā)詳解流程

    Apache Shiro是一個(gè)強(qiáng)大且易用的Java安全框架,執(zhí)行身份驗(yàn)證、授權(quán)、密碼和會(huì)話(huà)管理。使用Shiro的易于理解的API,您可以快速、輕松地獲得任何應(yīng)用程序,從最小的移動(dòng)應(yīng)用程序到最大的網(wǎng)絡(luò)和企業(yè)應(yīng)用程序
    2021-10-10
  • Java通過(guò)jersey實(shí)現(xiàn)客戶(hù)端圖片上傳示例

    Java通過(guò)jersey實(shí)現(xiàn)客戶(hù)端圖片上傳示例

    本篇文章主要介紹了Java通過(guò)jersey實(shí)現(xiàn)客戶(hù)端圖片上傳示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2017-03-03
  • Spring IOC 三種配置方式詳解

    Spring IOC 三種配置方式詳解

    這篇文章主要介紹了Spring IOC 三種配置方式,基于xml配置方式組件管理,基于注解方式管理和配置類(lèi)方式管理,這三種方式,通過(guò)圖文講解的非常詳細(xì),需要的朋友可以參考下
    2024-05-05
  • 詳解在springboot中使用Mybatis Generator的兩種方式

    詳解在springboot中使用Mybatis Generator的兩種方式

    這篇文章主要介紹了詳解在springboot中使用Mybatis Generator的兩種方式,本文將介紹到在springboot的項(xiàng)目中如何去配置和使用MBG以及MBG生成代碼的兩種方式,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2018-11-11
  • Java線(xiàn)程池運(yùn)行狀態(tài)監(jiān)控實(shí)現(xiàn)解析

    Java線(xiàn)程池運(yùn)行狀態(tài)監(jiān)控實(shí)現(xiàn)解析

    這篇文章主要介紹了Java線(xiàn)程池運(yùn)行狀態(tài)監(jiān)控實(shí)現(xiàn)解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • java基于數(shù)據(jù)庫(kù)實(shí)現(xiàn)全局唯一ID的示例

    java基于數(shù)據(jù)庫(kù)實(shí)現(xiàn)全局唯一ID的示例

    本文主要介紹了java基于數(shù)據(jù)庫(kù)實(shí)現(xiàn)全局唯一ID的示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • 一篇文章帶你認(rèn)識(shí)Java8接口的默認(rèn)方法

    一篇文章帶你認(rèn)識(shí)Java8接口的默認(rèn)方法

    這篇文章主要給大家介紹了如何通過(guò)一篇文章帶你認(rèn)識(shí)Java8接口的默認(rèn)方法的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Java8具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • java對(duì)象轉(zhuǎn)換String類(lèi)型的三種方法

    java對(duì)象轉(zhuǎn)換String類(lèi)型的三種方法

    在很多情況下我們都需要將一個(gè)對(duì)象轉(zhuǎn)換為String類(lèi)型。一般來(lái)說(shuō)有三種方法可以實(shí)現(xiàn):Object.toString()、(String)Object、String.valueOf(Object)。下面對(duì)這三種方法一一分析
    2013-11-11
  • PowerJob的QueryConvertUtils工作流程源碼解讀

    PowerJob的QueryConvertUtils工作流程源碼解讀

    這篇文章主要為大家介紹了PowerJob的QueryConvertUtils工作流程源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01

最新評(píng)論

鸡东县| 温泉县| 美姑县| 沽源县| 土默特右旗| 青州市| 安徽省| 封丘县| 隆回县| 牟定县| 龙南县| 睢宁县| 台山市| 墨竹工卡县| 册亨县| 海宁市| 阿勒泰市| 兴安盟| 宿州市| 辰溪县| 都昌县| 湛江市| 津市市| 安达市| 古田县| 抚顺市| 鄂尔多斯市| 枞阳县| 锦州市| 泾川县| 于都县| 彩票| 伊吾县| 汶川县| 古丈县| 景德镇市| 河北区| 闽侯县| 鄂州市| 湟中县| 辽源市|