日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HashMap线程不安全的原因和解决方案

發布時間:2024/1/18 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HashMap线程不安全的原因和解决方案 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1、HashMap線程不安全原因:

JDK1.8 中,由于多線程對HashMap進行put操作,調用了HashMap#putVal(),具體原因:假設兩個線程A、B都在進行put操作,并且hash函數計算出的插入下標是相同的,當線程A執行完第六行代碼后由于時間片耗盡導致被掛起,而線程B得到時間片后在該下標處插入了元素,完成了正常的插入,然后線程A獲得時間片,由于之前已經進行了hash碰撞的判斷,所有此時不會再進行判斷,而是直接進行插入,這就導致了線程B插入的數據被線程A覆蓋了,從而線程不安全!!!

JDK1.8 HashMap線程不安全體現在:數據覆蓋

二、HashMap線程不安全、死循環、數據丟失、數據覆蓋的原因

final V putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict) {Node<K,V>[] tab; Node<K,V> p; int n, i;if ((tab = table) == null || (n = tab.length) == 0)n = (tab = resize()).length;if ((p = tab[i = (n - 1) & hash]) == null) //此處是判斷是否進行了hash碰撞tab[i] = newNode(hash, key, value, null);else {Node<K,V> e; K k;if (p.hash == hash &&((k = p.key) == key || (key != null && key.equals(k))))e = p;else if (p instanceof TreeNode)e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);else {for (int binCount = 0; ; ++binCount) {if ((e = p.next) == null) {p.next = newNode(hash, key, value, null);if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1sttreeifyBin(tab, hash);break;}if (e.hash == hash &&((k = e.key) == key || (key != null && key.equals(k))))break;p = e;}}if (e != null) { // existing mapping for keyV oldValue = e.value;if (!onlyIfAbsent || oldValue == null)e.value = value;afterNodeAccess(e);return oldValue;}}++modCount;if (++size > threshold)resize();afterNodeInsertion(evict);return null;}

其中第六行代碼是判斷是否出現hash碰撞,假設兩個線程A、B都在進行put操作,并且hash函數計算出的插入下標是相同的,當線程A執行完第六行代碼后由于時間片耗盡導致被掛起,而線程B得到時間片后在該下標處插入了元素,完成了正常的插入,然后線程A獲得時間片,由于之前已經進行了hash碰撞的判斷,所有此時不會再進行判斷,而是直接進行插入,這就導致了線程B插入的數據被線程A覆蓋了,從而線程不安全!!!

除此之前,還有就是代碼的第38行處有個++size,我們這樣想,還是線程A、B,這兩個線程同時進行put操作時,假設當前HashMap的zise大小為10,當線程A執行到第38行代碼時,從主內存中獲得size的值為10后準備進行+1操作,但是由于時間片耗盡只好讓出CPU,線程B快樂的拿到CPU還是從主內存中拿到size的值10進行+1操作,完成了put操作并將size=11寫回主內存,然后線程A再次拿到CPU并繼續執行(此時size的值仍為10),當執行完put操作后,還是將size=11寫回內存,此時,線程A、B都執行了一次put操作,但是size的值只增加了1,所有說還是由于數據覆蓋又導致了線程不安全!!!

三、如何使HashMap在多線程情況下進行線程安全操作?

使用 Collections.synchronizedMap(map),包裝成同步Map,原理就是在HashMap的所有方法上synchronized

synchronized 關鍵字,代表這個方法加鎖,相當于不管哪一個線程(例如線程A),運行到這個方法時,都要檢查有沒有其它線程B(或者C、 D等)正在用這個方法(或者該類的其他同步方法),有的話要等正在使用synchronized方法的線程B(或者C 、D)運行完這個方法后再運行此線程A,沒有的話,鎖定調用者,然后直接運行!!!

例如:Collections.SynchronizedMap#get()

public V get(Object key) {synchronized (mutex) {return m.get(key);} }

原文轉自:https://juejin.cn/post/6917526751199526920

總結

以上是生活随笔為你收集整理的HashMap线程不安全的原因和解决方案的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 日韩国产精品一区二区 | av成人免费观看 | 美女啪啪免费视频 | 日韩免费视频 | 91精品啪在线观看国产 | 国产精品视频 | 男人亚洲天堂 | 日韩黄色一级大片 | 久久久精品91| av免费观看不卡 | 国产一区二区三区四区五区六区 | 一本—道久久a久久精品蜜桃 | 国产亚洲欧美在线视频 | 男女羞羞的视频 | 日韩高清在线观看一区 | 就要日就要操 | 久久久久久久久久久久久女国产乱 | 日本免费一区二区三区四区 | 在线看日韩av | 欧美综合激情 | 黄色污在线观看 | 久久精品视频免费播放 | 欧美一区二区三区大屁股撅起来 | 亚洲特级黄色片 | 久久黄网 | 啪啪啪一区二区 | 亚洲一区免费 | 色悠久 | 一区二区日韩精品 | 天天干视频在线观看 | 国产精品美女久久久久图片 | 最新日韩视频 | 粉嫩av一区 | 狠狠躁夜夜 | 青青草视频免费播放 | 天天免费看av | 色爽爽爽爽爽爽爽爽 | 中文字字幕在线中文 | 美女屁股眼视频网站 | www插插插| 免费观看一区二区三区 | 99精品黄色 | 午夜国产免费 | 亚洲激情视频网 | 黄色在线免费观看 | 在线观看av片 | 韩国三级av | 国产免费内射又粗又爽密桃视频 | 性xxxx搡xxxxx搡欧美 | 四虎国产成人精品免费一女五男 | 美女扒开腿让男生桶 | 成人在线观看免费高清 | 卡一卡二在线视频 | 久久精品国产电影 | 免费观看毛片网站 | 婷婷影院在线观看 | 最新日本中文字幕 | 操操操操操操操操操 | 久久国产一级 | 国产极品免费 | 日批视频在线 | 久久潮| 四虎精品在永久在线观看 | 自拍1区 | 丁香婷婷视频 | 成人午夜激情视频 | 欧美日韩理论 | 欧美性xxxx | 色呦呦在线播放 | 18av在线视频 | 色视频免费在线观看 | 亚洲五月六月 | 亚洲影视在线 | 亚欧日韩av | 永久免费看片在线观看 | 日本理论片中文字幕 | 精品乱子伦一区二区三区 | 国产suv精品一区 | 黄色网久久 | 99re这里都是精品 | 亚洲色图.com | 精品人妻少妇一区二区三区 | 小早川怜子一区二区三区 | 91偷拍精品一区二区三区 | 国产伦精品视频一区二区三区 | 国产欧美激情在线观看 | 黄视频免费看在线 | 亚洲国产精品视频在线观看 | 久久久99精品国产一区二区三区 | 国产色黄 | 丝袜在线一区 | 欧美性网站 | 亚洲精品久久久久国产 | 性一交一乱一色一免费无遮挡 | xxxxx黄色片 噜噜噜噜噜色 | www.五月天婷婷 | 亚洲精品在线观看av | 国产av自拍一区 | 无码粉嫩虎白一线天在线观看 |