hashmap在jdk7之前,會產生死鏈和資料丟失這個問題
hashmap進行儲存時,如果size超過當前最大容量*負載因子時候會發生resize,首先看一下resize原**
void resize(int newcapacity)
entry newtable = new entry[newcapacity];
transfer(newtable);
table = newtable;
threshold = (int)(newcapacity * loadfactor);
}
而這段**中又呼叫了transfer()方法,而這個方法實現的機制就是將每個鍊錶轉化到新鍊錶,並且鍊錶中的位置發生反轉(因為原始碼在處理鍊錶的時候,會依把遍歷到的每個節點插在頭結點位置處),而這在多執行緒情況下是很容易造成鍊錶迴路,從而發生get()死迴圈,我們看一下他的源**
void transfer(entry newtable) while (e != null);}}
}
那麼為什麼會產生死鏈呢?
在多執行緒情況下,假設有兩個執行緒p1、p2,在擴容時操作hashmap,此時的鍊錶為 a->b->null
1、p1先執行,執行完"entrynext = e.next;"**後發生阻塞,或者其他情況不再執行下去,此時e=a,next=b
2、而p2已經執行完整段**,鍊錶順序會變為之前的倒序,於是當前的新鍊錶newtable[i]為b->a->null
3、p1又繼續執行"entrynext = e.next;"之後的**,則執行完"e=next;"後,即為讓a指向b,但是執行緒p2中已經是b指向a了,那麼newtable[i]為a<->b,則造成死鏈,while(e!=null)一直死迴圈
死鏈也可能由別的情況產生,這只是一種容易理解的。
還有資料丟失的情況,可以看下面的部落格。
參考
linux多執行緒下之死鎖
出現死鎖需要同時滿足四個條件,有乙個不具備,系統就不會出現死鎖。互斥條件。即某個資源在一段時間內只能由乙個程序占有,不能同時被兩個或兩個以上的程序占有。這種獨佔資源如cd rom驅動器,印表機等等,必須在占有該資源的程序主動釋放它之後,其它程序才能占有該資源。這是由資源本身的屬性所決定的。如獨木橋就...
多執行緒死鎖
這段時間剛好學到多執行緒,下面是自己對死鎖的一些感悟,並不是我說的有多到位,只是想到一種更為通俗易懂理解方式,現在和大家一起分享一下,有改進的地方,希望大家多提提意見。一 首先說一下死鎖的定義 由兩個或兩個以上的執行緒由於互相競爭資源,導致一種互相等待的狀態,如果沒有外力推動,則他們都無法進行下去。...
多執行緒死鎖
1 提出 多執行緒與多程序提高了系統資源的利用率,然而併發執行也會帶來一些問題,如死鎖。2 概念 死鎖是指兩個或兩個以上的程序在執行過程中,由於競爭資源或者由於彼此通訊而造成的一種阻塞的現象,若無外力作用,它們都將無法推進下去。此時稱系統處於死鎖狀態或系統產生了死鎖,這些永遠在互相等待的程序稱為死鎖...