日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

Java之currenHashMap

發(fā)布時間:2025/5/22 55 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java之currenHashMap 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

? ? ? ? currenHashMap是jkd1.5引入的,其特點是:效率比Hashtable高,并發(fā)性比HashMap好。結(jié)合了兩者的特點。

??????? ConcurrentHashMap是一個線程安全的Hash Table,它的主要功能是提供了一組和HashTable功能相同但是線程安全的方法。ConcurrentHashMap可以做到讀取數(shù)據(jù)不加鎖,并且其內(nèi)部的結(jié)構(gòu)可以讓其在進行寫操作的時候能夠?qū)㈡i的粒度保持地盡量地小,不用對整個ConcurrentHashMap加鎖。

??????? ConcurrentHashMap為了提高本身的并發(fā)能力,在內(nèi)部采用了一個叫做Segment的結(jié)構(gòu),一個Segment其實就是一個類Hash Table的結(jié)構(gòu),Segment內(nèi)部維護了一個鏈表數(shù)組,我們用下面這一幅圖來看下ConcurrentHashMap的內(nèi)部結(jié)構(gòu):

??????? 從上面的結(jié)構(gòu)我們可以了解到,ConcurrentHashMap定位一個元素的過程需要進行兩次Hash操作,第一次Hash定位到Segment,第二次Hash定位到元素所在的鏈表的頭部,因此,這一種結(jié)構(gòu)的帶來的副作用是Hash的過程要比普通的HashMap要長,但是帶來的好處是寫操作的時候可以只對元素所在的Segment進行加鎖即可,不會影響到其他的Segment,這樣,在最理想的情況下,ConcurrentHashMap可以最高同時支持Segment數(shù)量大小的寫操作(剛好這些寫操作都非常平均地分布在所有的Segment上),所以,通過這一種結(jié)構(gòu),ConcurrentHashMap的并發(fā)能力可以大大的提高。

??????? HashMap中未進行同步考慮,而Hashtable則使用了synchronized,帶來的直接影響就是可選擇,我們可以在單線程時使用HashMap提高效率,而多線程時用Hashtable來保證安全。通過分析Hashtable就知道,synchronized是針對整張Hash表的,即每次鎖住整張表讓線程獨占,安全的背后是巨大的浪費。

?

??????? 左邊便是Hashtable的實現(xiàn)方式---鎖整個hash表;而右邊則是ConcurrentHashMap的實現(xiàn)方式---段鎖。它使用了多個鎖來控制對hash表的不同部分進行的修改。?ConcurrentHashMap將hash表分為16段(默認(rèn)值),諸如get,put,remove等常用操作只鎖當(dāng)前需要用到的段。試想,原來 只能一個線程進入,現(xiàn)在卻能同時16個寫線程進入(寫線程才需要鎖定,而讀線程幾乎不受限制,之后會提到),并發(fā)性的提升是顯而易見的。

?? ? ? ? ConcurrentHashMap的讀取并發(fā),因為在讀取的大多數(shù)時候都沒有用到鎖定,所以讀取操作幾乎是完全的并發(fā)操作,而寫操作鎖定的粒度又非常細(xì),比起之前又更加快速(這一點在桶更多時表現(xiàn)得更明顯些)。只有在求size()containsValue()等操作時才需要鎖定整個表。它們可能需要鎖定整個 表而而不僅僅是某個段,這需要按順序鎖定所有段,操作完畢后,又按順序釋放所有段的鎖(防止死鎖)。

??????? 讀是否要加鎖,因為讀寫會發(fā)生沖突?ConcurrentHashMap完全允許多個讀操作并發(fā)進行,讀操作并不需要加鎖。如果使 用傳統(tǒng)的技術(shù),如HashMap中的實現(xiàn),如果允許可以在hash鏈的中間添加或刪除元素,讀操作不加鎖將得到不一致的數(shù)據(jù)。 ConcurrentHashMap實現(xiàn)技術(shù)是保證HashEntry幾乎是不可變的。HashEntry代表每個hash鏈中的一個節(jié)點,其結(jié)構(gòu)如下所 示:

static final class HashEntry<K,V> {

final K key;

final int hash;

volatile V value;

final HashEntry<K,V> next;

}

? ? ? 可以看到HashEntry的一個特點,除了value以外,其他的幾個變量都是final的,這樣做是為了防止鏈表結(jié)構(gòu)被破壞,出現(xiàn)ConcurrentModification的情況。為了確保讀操作能夠看到最新的值,將value設(shè)置成volatile,這避免了加鎖。在當(dāng)前的Java內(nèi)存模型下,線程可以把變量保存在本地內(nèi)存(比如機器的寄存器)中,而不是直接在主存中進行讀寫。這就可能造成一個線程在主存中修改了一個變量的值,而另外一個線程還繼續(xù)使用它在寄存器中的變量值的拷貝,造成數(shù)據(jù)的不一致。volatile關(guān)鍵字指示JVM,這個變量是不穩(wěn)定的,每次使用它都到主存中進行讀取。一般說來,多任務(wù)環(huán)境下各任務(wù)間共享的標(biāo)志都應(yīng)該加volatile修飾。Volatile修飾的成員變量在每次被線程訪問時,都強迫從共享內(nèi)存中重讀該成員變量的值。而且,當(dāng)成員變量發(fā)生變化時,強迫線程將變化值回寫到共享內(nèi)存。這樣在任何時刻,兩個不同的線程總是看到某個成員變量的同一個值。

--------------------------------------------------------------------

PS:?歡迎關(guān)注公眾號"Devin說",會不定期更新Java相關(guān)技術(shù)知識。

--------------------------------------------------------------------

其他請參考:http://www.cnblogs.com/maxupeng/archive/2011/06/26/2090517.html

轉(zhuǎn)載于:https://www.cnblogs.com/devinzhang/archive/2012/02/24/2366678.html

總結(jié)

以上是生活随笔為你收集整理的Java之currenHashMap的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。