祁東網(wǎng)站設(shè)計公司網(wǎng)站統(tǒng)計工具有哪些
Hashtable和HashMap的區(qū)別
? ? ? ??HashMap和Hashtable都是哈希表數(shù)據(jù)結(jié)構(gòu),但是Hashtable是線程安全的,HashMap是線程不安全的
????????Hashtable實現(xiàn)線程安全就是簡單的把關(guān)鍵方法都加上了synchronized關(guān)鍵字
? ? ? ? 直接在方法上添加synchronized相當于針對this對象(Hashtable對象)加鎖,一個Hashtable只有一把鎖,所以當我們對Hashtable執(zhí)行任何操作的時候都會觸發(fā)鎖沖突,效率是非常低的
????????Hashtable是存在很多問題
????????1.
? ? ? ? 由于直接對方法進行加鎖,所以當有很多線程需要訪問Hashtable時就會導(dǎo)致嚴重的鎖沖突
???????? 2.
? ? ? ?當我們向Hashtable中添加數(shù)據(jù)時,對應(yīng)的size屬性應(yīng)該增加,此時就涉及到多個線程修改同一個變量,存在線程安全問題,而size屬性也是通過synchronized來解決線程安全問題的,所以效率會很低
???????? 3.
? ? ? ?哈希表有一個特性,當存放到哈希表中的數(shù)據(jù)越來越多,沖突率達到一定的數(shù)值,就會觸發(fā)擴容,一旦觸發(fā)擴容,就會由當前的線程去完成整個擴容過程,這個過程涉及到大量的元素拷貝,效率會很低
? ? ? ? 可能會出現(xiàn)一種情況:其他的線程都執(zhí)行得很流暢,突然有一個線程就卡住了,并且卡了很長的時間,此時這個線程就可能觸發(fā)了哈希表的擴容,這個擴容過程持續(xù)的時間很長
ConcurrentHashMap和Hashtable的區(qū)別
????????ConcurrentHashMap是線程安全的,并且在多線程編程中ConcurrentHashMap 是比Hashtable實用很多的
????????ConcurrentHashMap相比于Hashtable做了很多的優(yōu)化
? ? ? ? 1.
? ? ? ? 讀操作沒有加鎖,只對寫操作加鎖,加鎖用的也是synchronized,但是不是直接在方法上進行加鎖,而是針對哈希表上的每個鏈表加鎖,并且加鎖用的也不是this對象,而是直接用每個鏈表的頭結(jié)點作為鎖對象進行加鎖,相當于哈希表上每個鏈表都有各自的鎖對象
? ? ? ? 為什么要這樣設(shè)計呢?
? ? ? ? 因為多個線程對哈希表進行訪問時,如果訪問的是哈希表上不同的鏈表,實際上是不會出現(xiàn)線程安全問題的,只有多個線程訪問哈希表上的同一個鏈表才會出現(xiàn)線程安全問題,所以我們不需要對整個哈希表加鎖,我們只需要對每個鏈表進行加鎖即可
? ? ? ? 加這么多鎖不會消耗很多資源嗎?
? ? ? ? 可能會有細心的小伙伴有這樣的問題,但實際上我們用synchronized進行加鎖時,一開始加上的是一個偏向鎖,偏向鎖就相當于是一個標記,此時并沒有真正的實例化一個鎖出來,也就沒有消耗什么資源,只有當多個線程爭奪同一把鎖(出現(xiàn)鎖競爭)時才會去真正的實例化具體的鎖,而實際上多個線程去修改同一個鏈表上的數(shù)據(jù),這種情況是很少發(fā)生的,所以我們加上的鎖大多數(shù)都只是一個偏向鎖,不消耗什么資源
? ? ? ? 2.
????????充分利用 CAS 特性. 比如 size 屬性通過 CAS 來更新. 避免出現(xiàn)重量級鎖的情況.(關(guān)于CAS推薦看CAS的ABA問題)
? ? ? ? 3.
? ? ? ? 優(yōu)化了擴容方式,化整為零
? ? ? ? 當莫一個線程觸發(fā)了哈希表的擴容操作,此時不需要這個線程完成所有的擴容過程,當前這個線程只需要創(chuàng)建一個更大的哈希表,然后搬運一小部分數(shù)據(jù)即可
? ? ? ? 在擴容的期間,新舊數(shù)組是同時存在的,之后每個訪問ConcurrentHashMap的線程都會參與對數(shù)據(jù)的搬運,每個操作負責搬運一部分元素
? ? ? ? 在這個期間,我們修改數(shù)據(jù)會將數(shù)據(jù)直接修改到新數(shù)組上,添加數(shù)據(jù)會直接添加到新數(shù)組上,查找數(shù)據(jù)是新舊數(shù)組一起查找
? ? ? ? 當舊數(shù)組上的數(shù)據(jù)被全部搬運完成后,便會刪除舊數(shù)組
ConcurrentHashMap的鎖分段技術(shù)
????????簡單的說就是把若干個哈希桶分成一個 "段" (Segment), 針對每個段分別加鎖. 目的也是為了降低鎖競爭的概率. 當兩個線程訪問的數(shù)據(jù)恰好在同一個段上的時候, 才觸發(fā)鎖競爭.,但現(xiàn)在鎖分段技術(shù)技術(shù)已經(jīng)被淘汰了,因為要對哈希表的鏈表進行分段,管理起來是很麻煩的,不如直接對每個鏈表進行加鎖(鎖對象是鏈表的頭結(jié)點)