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

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

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

Java的fail fast機(jī)制

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

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

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

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

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

口說無憑,我們來看看源碼。就拿LinkedList來舉例,代碼如下所示:

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對象,用于遍歷。LinkedList也不例外,它重寫了listIterator()方法,返回了一個(gè)自定義的ListItr對象。

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();
	}
}

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

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

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

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

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

不是的,只要你在查詢數(shù)據(jù)的時(shí)候,繞開包含了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()沒有修改modCount的值,peekFirst()也沒有去檢查modCount,fail fast不復(fù)存在,就不會(huì)報(bào)錯(cuò)。

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

相關(guān)文章

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

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

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

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

    在一個(gè)業(yè)務(wù)流程中,需要多條DML(insert、delete、update)語句聯(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對象的一種方式推薦

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

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

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

    這篇文章主要介紹了synchronized的參數(shù)及其含義詳解,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(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通過注解下載任意對象

    SpringBoot通過注解下載任意對象

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

    解決springdataJPA對原生sql支持的問題

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

    詳解java裝飾模式(Decorator Pattern)

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

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

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

最新評論

娄底市| 拜泉县| 灵石县| 五常市| 定边县| 普宁市| 福鼎市| 永仁县| 桦甸市| 永福县| 买车| 巴林右旗| 咸丰县| 永平县| 临泽县| 鄱阳县| 齐齐哈尔市| 富宁县| 全州县| 通山县| 垫江县| 将乐县| 平乡县| 含山县| 抚顺县| 攀枝花市| 三亚市| 连州市| 丰原市| 苗栗市| 阿巴嘎旗| 拜城县| 台安县| 花莲县| 寻甸| 湘乡市| 新龙县| 永安市| 保德县| 措勤县| 台北市|