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

Java集合包中的fail fast機(jī)制詳解

 更新時(shí)間:2023年12月15日 09:39:47   作者:愛(ài)喝咖啡的程序員  
這篇文章主要介紹了Java集合包中的fail fast機(jī)制詳解,當(dāng)我們使用iterator迭代器遍歷一個(gè)集合的過(guò)程中,如果其它線程,或者它自己向這個(gè)集合新增或刪除了一個(gè)key-value,那么當(dāng)前線程就會(huì)拋出ConcurrentModificationException異常,需要的朋友可以參考下

Java的fail fast機(jī)制

首先說(shuō)說(shuō)現(xiàn)象,當(dāng)我們使用iterator迭代器遍歷一個(gè)集合的過(guò)程中,如果其它線程,或者它自己向這個(gè)集合新增或刪除了一個(gè)key-value,那么當(dāng)前線程就會(huì)拋出ConcurrentModificationException異常。

然后說(shuō)說(shuō)原理。無(wú)論是AbstractList,還是HashMap,它們都擁有一個(gè)modCount變量,每當(dāng)我們向集合新增或者刪除元素,都會(huì)使modCount的值增加1,這個(gè)參數(shù)就好像集合的操作版本號(hào)。當(dāng)我們?cè)诘?,?huì)創(chuàng)建一個(gè)expectedModCount,記錄了迭代之前的操作版本號(hào),每次迭代獲取數(shù)據(jù)時(shí),都會(huì)檢查一下,當(dāng)前的modCount是否與expectedModCount想等,若不相等,則說(shuō)明在當(dāng)前線程迭代遍歷元素時(shí),有其他的線程操作了集合。

集合包下面的集合都不是線程安全的,都會(huì)有并發(fā)問(wèn)題,所以都包含modCount變量。使用fail fast機(jī)制,當(dāng)一個(gè)線程在迭代遍歷,另一個(gè)線程在新增、刪除元素時(shí),就會(huì)立刻報(bào)錯(cuò)。

注意: 一個(gè)線程在迭代遍歷,另一個(gè)線程在修改元素時(shí),并不會(huì)觸發(fā)fail fast??梢钥碅rrayList和LinkedList的set()源碼,沒(méi)有發(fā)現(xiàn)modCount的痕跡(你只要不刪除,或者新增元素,就沒(méi)問(wèn)題)。

并且,fail fast僅僅是一個(gè)錯(cuò)誤檢測(cè)機(jī)制,因?yàn)镴DK并不能保證fail fast一定會(huì)發(fā)生。若在多線程環(huán)境下使用fail-fast機(jī)制的集合,建議使用“java.util.concurrent包下的類”去取代“java.util包下的類”。

口說(shuō)無(wú)憑,我們來(lái)看看源碼。就拿LinkedList來(lái)舉例,代碼如下所示:

LinkedList<String> list = new LinkedList<>();
list.add("123");
list.add("456");
list.add("789");
for (String str : list) {
	list.remove();
}

首次執(zhí)行l(wèi)ist.remove()是不會(huì)報(bào)錯(cuò)的,但是當(dāng)進(jìn)入下一輪循環(huán)時(shí),就會(huì)報(bào)錯(cuò)。

當(dāng)我們使用for循環(huán)遍歷任何一個(gè)List之前,底層都會(huì)調(diào)用listIterator( )方法,創(chuàng)建一個(gè)ListIterator對(duì)象,用于遍歷。LinkedList也不例外,它重寫(xiě)了listIterator()方法,返回了一個(gè)自定義的ListItr對(duì)象。

public ListIterator<E> listIterator(int index) {
	checkPositionIndex(index);
	return new ListItr(index);
}
private class ListItr implements ListIterator<E> {
	// 省略..
	private int expectedModCount = modCount;
	ListItr(int index) {
		省略..
	}
	public E next() {
		checkForComodification();
		省略..
	}
	final void checkForComodification() {
		if (modCount != expectedModCount)
			throw new ConcurrentModificationException();
	}
}

我省略了許多與本文無(wú)關(guān)的代碼,關(guān)鍵代碼就那么幾句。執(zhí)行l(wèi)istIerator()方法時(shí),一定會(huì)創(chuàng)建一個(gè)ListItr對(duì)象,同時(shí)一定會(huì)初始化它的成員變量expectedModCount,等于當(dāng)前的modCount。

接下來(lái)就是遍歷,遍歷無(wú)非就是獲取List中的下一個(gè)元素,用屁股想想,調(diào)用的不就是next()方法么,next()方法一上來(lái)就執(zhí)行了checkForComodification(),比較一下當(dāng)前的modCount是否與expectedModCount一樣,如果不一樣,就拋出異常。

這個(gè)意思不就是在說(shuō),如果在遍歷List的過(guò)程中,你敢做新增或者刪除操作(累加了modCount的值),那就會(huì)報(bào)錯(cuò)。

值得注意的是,報(bào)錯(cuò)的地方不是list.remove(),報(bào)錯(cuò)的是你做了新增、刪除操作后的接下來(lái)的一輪遍歷時(shí),獲取數(shù)據(jù)時(shí)會(huì)報(bào)錯(cuò)。

那是不是只要遍歷集合時(shí),新增或者刪除(或者其它改變modCount的操作),都會(huì)報(bào)錯(cuò)呢?

不是的,只要你在查詢數(shù)據(jù)的時(shí)候,繞開(kāi)包含了modCount檢查的方法,就不會(huì)報(bào)錯(cuò)。

String str;
while((str = list.peekFirst()) != null) {
	System.out.println(str);
	list.pop();
}

上面的代碼也是在遍歷鏈表,但是不會(huì)報(bào)錯(cuò),因?yàn)閘ist.pop()沒(méi)有修改modCount的值,peekFirst()也沒(méi)有去檢查modCount,fail fast不復(fù)存在,就不會(huì)報(bào)錯(cuò)。

到此這篇關(guān)于Java集合包中的fail fast機(jī)制詳解的文章就介紹到這了,更多相關(guān)Java的fail fast機(jī)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解spring cloud hystrix緩存功能的使用

    詳解spring cloud hystrix緩存功能的使用

    這篇文章主要介紹了詳解spring cloudhystrix緩存功能的使用,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • Spring事務(wù)管理的全解析

    Spring事務(wù)管理的全解析

    在一個(gè)業(yè)務(wù)流程中,需要多條DML(insert、delete、update)語(yǔ)句聯(lián)合才能完成,本文介紹了Spring事務(wù)管理的各個(gè)方面,感興趣的朋友跟隨小編一起看看吧
    2026-02-02
  • Java中的@PreAuthorize注解源碼解析

    Java中的@PreAuthorize注解源碼解析

    這篇文章主要介紹了Java中的@PreAuthorize注解源碼解析,@PreAuthorize注解會(huì)在方法執(zhí)行前進(jìn)行權(quán)限驗(yàn)證,支持Spring?EL表達(dá)式,它是基于方法注解的權(quán)限解決方案,需要的朋友可以參考下
    2023-10-10
  • SpringBoot 普通類調(diào)用Bean對(duì)象的一種方式推薦

    SpringBoot 普通類調(diào)用Bean對(duì)象的一種方式推薦

    這篇文章主要介紹了SpringBoot 普通類調(diào)用Bean對(duì)象的一種方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • 關(guān)于synchronized的參數(shù)及其含義

    關(guān)于synchronized的參數(shù)及其含義

    這篇文章主要介紹了synchronized的參數(shù)及其含義詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • java題解Leetcode 8字符串轉(zhuǎn)換整數(shù)

    java題解Leetcode 8字符串轉(zhuǎn)換整數(shù)

    這篇文章主要為大家介紹了java題解Leetcode 8字符串轉(zhuǎn)換整數(shù)實(shí)現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • SpringBoot通過(guò)注解下載任意對(duì)象

    SpringBoot通過(guò)注解下載任意對(duì)象

    下載功能應(yīng)該是比較常見(jiàn)的功能了,雖然一個(gè)項(xiàng)目里面可能出現(xiàn)的不多,但是基本上每個(gè)項(xiàng)目都會(huì)有,而且有些下載功能其實(shí)還是比較繁雜的,這篇文章主要介紹了SpringBoot一個(gè)注解就能幫你下載任意對(duì)象,需要的朋友可以參考下
    2023-08-08
  • 解決springdataJPA對(duì)原生sql支持的問(wèn)題

    解決springdataJPA對(duì)原生sql支持的問(wèn)題

    這篇文章主要介紹了解決springdataJPA對(duì)原生sql支持的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • 詳解java裝飾模式(Decorator Pattern)

    詳解java裝飾模式(Decorator Pattern)

    這篇文章主要為大家詳細(xì)介紹了java裝飾模式Decorator Pattern,這種類型的設(shè)計(jì)模式屬于結(jié)構(gòu)型模式,它是作為現(xiàn)有的類的一個(gè)包裝,對(duì)裝飾器模式感興趣的小伙伴們可以參考一下
    2016-04-04
  • Java排序算法之歸并排序簡(jiǎn)單實(shí)現(xiàn)

    Java排序算法之歸并排序簡(jiǎn)單實(shí)現(xiàn)

    這篇文章主要介紹了Java排序算法之歸并排序簡(jiǎn)單實(shí)現(xiàn),具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12

最新評(píng)論

青冈县| 奉节县| 资中县| 辽阳县| 彭州市| 夏河县| 富阳市| 衡南县| 玉田县| 灌云县| 鄂伦春自治旗| 红安县| 若羌县| 西华县| 平昌县| 电白县| 双桥区| 蒙自县| 西盟| 太仆寺旗| 洪泽县| 甘南县| 阜宁县| 葵青区| 兴隆县| 英超| 穆棱市| 永济市| 砚山县| 拜泉县| 甘肃省| 合江县| 汪清县| 通道| 海晏县| 招远市| 边坝县| 肇东市| 陇川县| 论坛| 岐山县|