摘要:和的區(qū)別和的區(qū)別是,在操作的方法上加入關(guān)鍵字,使得線程安全。使用進(jìn)行比較,或者傳入的比較器。基于,它自己的任務(wù)主要是維護(hù)保持順序的雙向鏈表。和的區(qū)別提供了一個(gè)高效的線程安全的訪問和更新的方式。在中的過程和類似。
HashTable和HashMap的區(qū)別
HashTable和HashMap的區(qū)別是,HashTable在操作table的方法上加入synchronized關(guān)鍵字,使得線程安全。實(shí)現(xiàn)方式和HashMap類似,但是HashTable沒有處理在某個(gè)槽下的值太多,鏈表過長(zhǎng)的情況。
TreeMap和HashMap的區(qū)別有序,二叉搜索樹,使用紅黑樹。使用key進(jìn)行比較,或者傳入的比較器。方法containsKey、get、put和remove的時(shí)間復(fù)雜度是log(n)。
LinkedHashMap與HashMap的區(qū)別LinkedHashMap保存了元素的插入順序,在遍歷時(shí)會(huì)遵循插入的順序。而HashMap遍歷時(shí),順序是按照table的順序,依次遍歷每一個(gè)槽中的鏈表,所以順序和插入順序完全不同。
LinkedHashMap在Node上加上了before和after屬性用以構(gòu)建保持原順序的雙向鏈表。
LinkeHashMap可以設(shè)置參數(shù),使其從插入順序變?yōu)樵L問順序。
LinkedHashMap基于HashMap,它自己的任務(wù)主要是維護(hù)保持順序的雙向鏈表。
ConcurrentHashMap ConcurrentHashMap和HashMap的區(qū)別java.util.concurrent;
ConcurrentHashMap提供了一個(gè)高效的、線程安全的訪問和更新HashMap的方式。較之HashTable,它沒有提供在整個(gè)table上的鎖,同步方式粒度更細(xì)。
如何實(shí)現(xiàn)并發(fā)訪問的安全看網(wǎng)上資料,舊版本的ConcurrentHashMap采用了分段的策略進(jìn)行同步。Hash步驟如下:
ConcurrentHashMap維護(hù)了一個(gè)segment數(shù)組,segment是一個(gè)鎖。
將key先hash到segment位置,每個(gè)segment存儲(chǔ)了一個(gè)真正的table。
再次hash,找到在table中的位置。
在table中的過程和HashMap類似。
所有并發(fā)訪問ConcurrentHashMap的線程會(huì)在每個(gè)segment上同步,所以線程可以并行的訪問不同的segment,減小了同步的粒度。
但是,在1.8中,使用的是sun.misc.Unsafe工具。它的作用有:
對(duì)變量和數(shù)組內(nèi)容的原子訪問,自定義內(nèi)存屏障
對(duì)序列化的支持
自定義內(nèi)存管理/高效的內(nèi)存布局
與原生代碼和其他JVM進(jìn)行互操作
對(duì)高級(jí)鎖的支持
ConcurrentHashMap對(duì)table的操作全部由sun.misc.Unsafe來完成:
static finalNode tabAt(Node [] tab, int i) { return (Node )U.getObjectVolatile(tab, ((long)i << ASHIFT) + ABASE); } static final boolean casTabAt(Node [] tab, int i, Node c, Node v) { //c表示舊值 //v表示新值 //更新前會(huì)驗(yàn)證舊值是否變化,如果變化說明期間被其它線程修改,則修改失敗 //外部使用該方法一般會(huì)使用一個(gè)循環(huán),以多次重試 return U.compareAndSwapObject(tab, ((long)i << ASHIFT) + ABASE, c, v); } static final void setTabAt(Node [] tab, int i, Node v) { U.putObjectVolatile(tab, ((long)i << ASHIFT) + ABASE, v); }
可以簡(jiǎn)單的理解為上述方法是原子性的,對(duì)目標(biāo)數(shù)據(jù)所在的內(nèi)存位置進(jìn)行了加鎖,整個(gè)操作過程中,對(duì)該部分內(nèi)存的讀、寫不會(huì)受其它線程的影響。可見,該方法的并發(fā)實(shí)現(xiàn)粒度更細(xì)。
還有一點(diǎn)需要注意,在并發(fā)操作時(shí),可能會(huì)出現(xiàn)有的線程開始擴(kuò)張或縮小table,但是有的線程卻試圖操作table的情況。因?yàn)榘徇wtable上元素的過程比較耗時(shí),所以,其它線程發(fā)現(xiàn)該table正在重建,會(huì)先將操作table的事情往后放一放,而是轉(zhuǎn)頭去幫助搬遷table,等table搬遷完畢再繼續(xù)自己的活。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/67915.html
摘要:說到復(fù)盤基礎(chǔ),并不是所有的都會(huì)復(fù)盤,沒那個(gè)時(shí)間更沒那個(gè)必要。比如,一些基礎(chǔ)的語法以及條件語句,極度簡(jiǎn)單。思前想后,我覺得整個(gè)計(jì)劃應(yīng)該從集合開始,而復(fù)盤的方式就是讀源碼。通常,隊(duì)列不允許隨機(jī)訪問隊(duì)列中的元素。 ?showImg(https://segmentfault.com/img/remote/1460000020029737?w=1080&h=711); 老讀者都知道,我是自學(xué)轉(zhuǎn)行...
摘要:的值是在上述方法中處理過的值,通過與當(dāng)前容量進(jìn)行,直接獲取到哈希表的位置。策略二,如果已經(jīng)很大了,擴(kuò)容已經(jīng)不可取,那么就采用紅黑樹結(jié)構(gòu)轉(zhuǎn)化鏈表。紅黑樹的創(chuàng)建不再詳述。紅黑樹的根就是中第一個(gè)節(jié)點(diǎn)。 java.util.Map Map中的自我引用 需要小心用易變的對(duì)象作為Map的key,這會(huì)導(dǎo)致Map的行為無法預(yù)測(cè)。Map也不可以將自己作為key,可以作為value,但是會(huì)導(dǎo)致equals...
摘要:抓住了迭代器模式的本質(zhì),即是迭代,賦予了它極高的地位。輸出結(jié)果輸出結(jié)果小結(jié)迭代器模式幾乎是種設(shè)計(jì)模式中最常用的設(shè)計(jì)模式,本文主要介紹了是如何運(yùn)用迭代器模式,并介紹了模塊生成迭代器的種方法,以及種生成迭代器的內(nèi)置方法。 showImg(https://segmentfault.com/img/bVbmv7W?w=4272&h=2848); 在軟件開發(fā)領(lǐng)域中,人們經(jīng)常會(huì)用到這一個(gè)概念——設(shè)...
閱讀 1611·2023-04-25 16:29
閱讀 949·2021-11-15 11:38
閱讀 2285·2021-09-23 11:45
閱讀 1410·2021-09-22 16:03
閱讀 2532·2019-08-30 15:54
閱讀 1198·2019-08-30 10:53
閱讀 2599·2019-08-29 15:24
閱讀 1095·2019-08-26 12:25