国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Java容器類研究9:其它Map

zilu / 344人閱讀

摘要:和的區(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上加上了beforeafter屬性用以構(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 final  Node 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

相關(guān)文章

  • Java 基礎(chǔ) | Collection 集合概覽

    摘要:說到復(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)行...

    codergarden 評(píng)論0 收藏0
  • Java容器研究8:HashMap

    摘要:的值是在上述方法中處理過的值,通過與當(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...

    zhichangterry 評(píng)論0 收藏0
  • Python進(jìn)階:設(shè)計(jì)模式之迭代器模式

    摘要:抓住了迭代器模式的本質(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è)...

    pubdreamcc 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<