1、首先我們需要簡單地了解一下hashmap資料結構
hashmap通常會用乙個指標陣列(假設為table)來做分散所有的key,當乙個key被加入時,會通過hash算
法通過key算出這個陣列的下標i,然後就把這個插到table[i]中,如果有兩個不同的key被算了。
但有時候兩個key算出的下標會是乙個i,那麼就叫衝突,又叫碰撞,這樣會在table[i]上形成乙個鍊錶。所以
如果鍊錶過多或過長,查詢演算法則會變成低效能的鍊錶遍歷,這是hash表的缺陷。
我們都知道hashmap初始容量大小為16,一般來說,hash表這個容器當有資料要插入時,都會檢查容量有沒有超過設定的thredhold,如果超過,需要增大hash表的尺寸,但是這樣一來,整個hash表裡的元素都需要被重算一遍。這叫rehash,這個成本相當的大。具體大家可以看看jdk原始碼
2、現在來討論死鎖產生的原因
hashmap是非執行緒安全,死鎖一般都是產生於併發情況下。我們假設有二個程序t1、t2,hashmap容量為2,t1執行緒放入key a、b、c、d、e。在t1執行緒中a、b、c hash值相同,於是形成乙個鏈結,假設為a->c->b,而d、e hash值不同,於是容量不足,需要新建乙個更大尺寸的hash表,然後把資料從老的hash表中
遷移到新的hash表中(refresh)。這時t2程序闖進來了,t1暫時掛起,t2程序也準備放入新的key,這時也
發現容量不足,也refresh一把。refresh之後原來的鍊錶結構假設為c->a,之後t1程序繼續執行,鏈結結構
為a->c,這時就形成a.next=b,b.next=a的環形鍊錶。一旦取值進入這個環形鍊錶就會陷入死迴圈。
3、替代方案
使用concurrenthashmap進行替代,concurrenthashmap是乙個執行緒安全的hash table。可能有人會使用hashtable。當然hashtable也是執行緒安全,但hashtable鎖定的是整個hash表,效率相對比較低。而concurrenthashmap可以做到讀取資料不加鎖,並且其內部的結構可以讓其在進行寫操作的時候能夠將鎖的粒度保持地盡量地小,
HashMap死鎖原因分析及原理
一 hashmap原理 1.hashmap的本質就是陣列和鍊錶。table是乙個entry陣列,每乙個陣列元素儲存乙個entry節點,而entry節點內部又連線著同樣key的下乙個entry節點,就構成了鍊錶。詳情見 hashmap原始碼分析 2.hashmap死鎖原因 hashmap會造成死鎖,因...
死鎖及死鎖產生原因條件
作業系統中有若干程序併發執行,它們不斷申請 使用 釋放系統資源,雖然系統的進 程協調 通訊機構會對它們進行控制,但也可能出現若干程序都相互等待對方釋放資源才能 繼續執行,否則就阻塞的情況。此時,若不借助外界因素,誰也不能釋放資源,誰也不能解 除阻塞狀態。根據這樣的情況,作業系統中的死鎖被定義為系統中...
死鎖產生的原因及條件
一 死鎖的定義 死鎖 是指兩個或兩個以上的程序在執行過程中,因爭奪資源而造成的一種互相等待的現象,若無外力作用,它們都將無法推進下去。二 原因 1 因為系統資源不足。2 資源分配不當等。3 程序執行推進順序不合適。如果系統資源充足,程序的資源請求都能夠得到滿足,死鎖出現的可能性就很低,否則就會因爭奪...