java 中modCount 詳解及源碼分析
modCount到底是干什么的呢
在ArrayList,LinkedList,HashMap等等的內(nèi)部實現(xiàn)增,刪,改中我們總能看到modCount的身影,modCount字面意思就是修改次數(shù),但為什么要記錄modCount的修改次數(shù)呢?
大家發(fā)現(xiàn)一個公共特點沒有,所有使用modCount屬性的全是線程不安全的,這是為什么呢?說明這個玩意肯定和線程安全有關(guān)系嘍,那有什么關(guān)系呢
閱讀源碼,發(fā)現(xiàn)這玩意只有在本數(shù)據(jù)結(jié)構(gòu)對應(yīng)迭代器中才使用,以HashMap為例:
private abstract class HashIterator<E> implements Iterator<E> {
Entry<K,V> next; // next entry to return
int expectedModCount; // For fast-fail
int index; // current slot
Entry<K,V> current; // current entry
HashIterator() {
expectedModCount = modCount;
if (size > 0) { // advance to first entry
Entry[] t = table;
while (index < t.length && (next = t[index++]) == null)
;
}
}
public final boolean hasNext() {
return next != null;
}
final Entry<K,V> nextEntry() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
Entry<K,V> e = next;
if (e == null)
throw new NoSuchElementException();
if ((next = e.next) == null) {
Entry[] t = table;
while (index < t.length && (next = t[index++]) == null)
;
}
current = e;
return e;
}
public void remove() {
if (current == null)
throw new IllegalStateException();
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
Object k = current.key;
current = null;
HashMap.this.removeEntryForKey(k);
expectedModCount = modCount;
}
}
由以上代碼可以看出,在一個迭代器初始的時候會賦予它調(diào)用這個迭代器的對象的mCount,如何在迭代器遍歷的過程中,一旦發(fā)現(xiàn)這個對象的mcount和迭代器中存儲的mcount不一樣那就拋異常
好的,下面是這個的完整解釋
Fail-Fast 機制
我們知道 java.util.HashMap 不是線程安全的,因此如果在使用迭代器的過程中有其他線程修改了map,那么將拋出ConcurrentModificationException,這就是所謂fail-fast策略。這一策略在源碼中的實現(xiàn)是通過 modCount 域,modCount 顧名思義就是修改次數(shù),對HashMap 內(nèi)容的修改都將增加這個值,那么在迭代器初始化過程中會將這個值賦給迭代器的 expectedModCount。在迭代過程中,判斷 modCount 跟 expectedModCount 是否相等,如果不相等就表示已經(jīng)有其他線程修改了 Map:注意到 modCount 聲明為 volatile,保證線程之間修改的可見性。
所以在這里和大家建議,當大家遍歷那些非線程安全的數(shù)據(jù)結(jié)構(gòu)時,盡量使用迭代器
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
- Java中包裝類介紹與其注意事項
- java實現(xiàn)字符串和日期類型相互轉(zhuǎn)換的方法
- java計算給定字符串中出現(xiàn)次數(shù)最多的字母和該字母出現(xiàn)次數(shù)的方法
- java HashMap內(nèi)部實現(xiàn)原理詳解
- Java中基于maven實現(xiàn)zxing二維碼功能
- Java將文件分割為多個子文件再將子文件合并成原始文件的示例
- java實現(xiàn)文件保存到本地的方法
- 詳解Java中“==”與equals()的區(qū)別
- Java 散列存儲詳解及簡單示例
- Java之Spring AOP 實現(xiàn)用戶權(quán)限驗證
- java Socket UDP實例詳解
相關(guān)文章
java使用BeanUtils.copyProperties踩坑經(jīng)歷
最近在做個項目,踩了個坑特此記錄一下,本文主要介紹了使用BeanUtils.copyProperties踩坑經(jīng)歷,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05
flyway實現(xiàn)java 自動升級SQL腳本的問題及解決方法
大家在平時開發(fā)自己寫SQL語句忘記在所有環(huán)境執(zhí)行,需要新增環(huán)境做數(shù)據(jù)遷移,那么遇到這樣的問題該如何解決呢?本文通過場景分析給大家介紹java 自動升級SQL腳本的策略,感興趣的朋友一起看看吧2021-07-07
java?啟動參數(shù)?springboot?idea詳解
這篇文章主要介紹了java?啟動參數(shù)?springboot?idea的相關(guān)知識,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-09-09
SpringMVC中的DispatcherServlet請求分析
這篇文章主要介紹了SpringMVC中的DispatcherServlet請求分析, DispatcherServlet作為一個Servlet,那么當有請求到Tomcat等Servlet服務(wù)器時,會調(diào)用其service方法,再調(diào)用到其父類GenericServlet的service方法,需要的朋友可以參考下2024-01-01
SpringCloud中的斷路器(Hystrix)和斷路器監(jiān)控(Dashboard)
本篇主要介紹的是SpringCloud中的斷路器(Hystrix)和斷路器指標看板(Dashboard)的相關(guān)使用知識,需要的朋友可以參考下2019-06-06
Java Big Number操作BigInteger及BigDecimal類詳解
這篇文章主要為大家介紹了Java Big Number操作BigInteger及BigDecimal類詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-07-07

