HashMap,HashTabel,ConcurrentHashMap

HashMap的初始化

int DEFAULT_INITIAL_CAPACITY = 16:默認(rèn)的初始容量為16 
int MAXIMUM_CAPACITY = 1 << 30:最大的容量為 2 ^ 30 
float DEFAULT_LOAD_FACTOR = 0.75f:默認(rèn)的加載因子為 0.75f 
Entry< K,V>[] table:Entry類型的數(shù)組凛篙,HashMap用這個(gè)來維護(hù)內(nèi)部的數(shù)據(jù)結(jié)構(gòu)昙衅,它的長度由容量決定 
int size:HashMap的大小 
int threshold:HashMap的極限容量另凌,擴(kuò)容臨界點(diǎn)(容量和加載因子的乘積)

每次新建一個(gè)HashMap時(shí)糕档,都會初始化一個(gè)table數(shù)組境析。table數(shù)組的元素為Entry節(jié)點(diǎn)

image.png

HashMap如何解決沖突

背景

散列表要解決的一個(gè)問題就是散列值的沖突問題义矛,通常是兩種方法:鏈表法和開放地址法妨托。

鏈表法就是將相同hash值的對象組織成一個(gè)鏈表放在hash值對應(yīng)的槽位缸榛;
開放地址法是通過一個(gè)探測算法,當(dāng)某個(gè)槽位已經(jīng)被占據(jù)的情況下繼續(xù)查找下一個(gè)可以使用的槽位

HashMap里面沒有出現(xiàn)hash沖突時(shí)兰伤,沒有形成單鏈表時(shí)内颗,hashmap查找元素很快,get()方法能夠直接定位到元素,但是出現(xiàn)單鏈表后敦腔,單個(gè)bucket 里存儲的不是一個(gè) Entry均澳,而是一個(gè) Entry 鏈,系統(tǒng)只能必須按順序遍歷每個(gè) Entry符衔,直到找到想搜索的 Entry 為止——如果恰好要搜索的 Entry 位于該 Entry 鏈的最末端(該 Entry 是最早放入該 bucket 中)找前,那系統(tǒng)必須循環(huán)到最后才能找到該元素.
創(chuàng)建 HashMap 時(shí),有一個(gè)默認(rèn)的負(fù)載因子(load factor)判族,其默認(rèn)值為 0.75躺盛,這是時(shí)間和空間成本上一種折衷:增大負(fù)載因子可以減少 Hash 表(就是那個(gè) Entry 數(shù)組)所占用的內(nèi)存空間,但會增加查詢數(shù)據(jù)的時(shí)間開銷五嫂,而查詢是最頻繁的的操作(HashMap 的 get() 與 put() 方法都要用到查詢)颗品;減小負(fù)載因子會提高數(shù)據(jù)查詢的性能肯尺,但會增加 Hash 表所占用的內(nèi)存空間

線程不安全的HashMap

因?yàn)槎嗑€程環(huán)境下,使用Hashmap進(jìn)行put操作會引起死循環(huán)躯枢,導(dǎo)致CPU利用率接近100%则吟,所以在并發(fā)情況下不能使用HashMap

final HashMap<String, String> map = new HashMap<String, String>(2);
Thread t = new Thread(new Runnable() {
      @Override
      public void run() {
         for (int i = 0; i < 10000; i++) {
              new Thread(new Runnable() {
                        @Override
                        public void run() {
                            map.put(UUID.randomUUID().toString(), "");
                        }
                    }, "ftf" + i).start();
                }
            }
      }, "ftf");
t.start();
t.join();

效率低下的HashTable容器

HashTable容器使用synchronized來保證線程安全,但在線程競爭激烈的情況下HashTable的效率非常低下锄蹂。因?yàn)楫?dāng)一個(gè)線程訪問HashTable的同步方法時(shí)氓仲,其他線程訪問HashTable的同步方法時(shí),可能會進(jìn)入阻塞或輪詢狀態(tài)得糜。如線程1使用put進(jìn)行添加元素敬扛,線程2不但不能使用put方法添加元素,并且也不能使用get方法來獲取元素朝抖,所以競爭越激烈效率越低啥箭。

ConcurrentHashMap的鎖分段技術(shù)

HashTable容器在競爭激烈的并發(fā)環(huán)境下表現(xiàn)出效率低下的原因,是因?yàn)樗性L問HashTable的線程都必須競爭同一把鎖治宣,那假如容器里有多把鎖急侥,每一把鎖用于鎖容器其中一部分?jǐn)?shù)據(jù),那么當(dāng)多線程訪問容器里不同數(shù)據(jù)段的數(shù)據(jù)時(shí)侮邀,線程間就不會存在鎖競爭坏怪,從而可以有效的提高并發(fā)訪問效率,這就是ConcurrentHashMap所使用的鎖分段技術(shù)绊茧,首先將數(shù)據(jù)分成一段一段的存儲铝宵,然后給每一段數(shù)據(jù)配一把鎖,當(dāng)一個(gè)線程占用鎖訪問其中一個(gè)段數(shù)據(jù)的時(shí)候华畏,其他段的數(shù)據(jù)也能被其他線程訪問鹏秋。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市唯绍,隨后出現(xiàn)的幾起案子拼岳,更是在濱河造成了極大的恐慌枝誊,老刑警劉巖况芒,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件率拒,死亡現(xiàn)場離奇詭異面氓,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)寺庄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進(jìn)店門祠够,熙熙樓的掌柜王于貴愁眉苦臉地迎上來压汪,“玉大人,你說我怎么就攤上這事古瓤≈蛊剩” “怎么了腺阳?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長穿香。 經(jīng)常有香客問我亭引,道長,這世上最難降的妖魔是什么皮获? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任焙蚓,我火速辦了婚禮,結(jié)果婚禮上洒宝,老公的妹妹穿的比我還像新娘购公。我一直安慰自己,他們只是感情好雁歌,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布宏浩。 她就那樣靜靜地躺著,像睡著了一般靠瞎。 火紅的嫁衣襯著肌膚如雪绘闷。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天较坛,我揣著相機(jī)與錄音印蔗,去河邊找鬼。 笑死丑勤,一個(gè)胖子當(dāng)著我的面吹牛华嘹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播法竞,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼耙厚,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了岔霸?” 一聲冷哼從身側(cè)響起薛躬,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎呆细,沒想到半個(gè)月后型宝,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡絮爷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年趴酣,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片坑夯。...
    茶點(diǎn)故事閱讀 39,773評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡岖寞,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出柜蜈,到底是詐尸還是另有隱情仗谆,我是刑警寧澤指巡,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站隶垮,受9級特大地震影響厌处,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜岁疼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一阔涉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧捷绒,春花似錦瑰排、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至字逗,卻和暖如春京郑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背葫掉。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工些举, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人俭厚。 一個(gè)月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓户魏,卻偏偏與公主長得像,于是被迫代替她去往敵國和親挪挤。 傳聞我的和親對象是個(gè)殘疾皇子叼丑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Java8張圖 11、字符串不變性 12扛门、equals()方法鸠信、hashCode()方法的區(qū)別 13、...
    Miley_MOJIE閱讀 3,701評論 0 11
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法论寨,類相關(guān)的語法星立,內(nèi)部類的語法,繼承相關(guān)的語法政基,異常的語法贞铣,線程的語...
    子非魚_t_閱讀 31,625評論 18 399
  • Java SE 基礎(chǔ): 封裝、繼承沮明、多態(tài) 封裝: 概念:就是把對象的屬性和操作(或服務(wù))結(jié)合為一個(gè)獨(dú)立的整體,并盡...
    Jayden_Cao閱讀 2,108評論 0 8
  • java筆記第一天 == 和 equals ==比較的比較的是兩個(gè)變量的值是否相等窍奋,對于引用型變量表示的是兩個(gè)變量...
    jmychou閱讀 1,497評論 0 3
  • 尊重原創(chuàng):(口訣)轉(zhuǎn)自http://lasombra.iteye.com/blog/991662 單目乘除為關(guān)系荐健,...
    ifeelok0319閱讀 395評論 0 0