Java集合之Hashtable

??今天來(lái)和大家嘮嘮HashTable,平時(shí)編碼的時(shí)候沒(méi)用過(guò)它,記憶中它和HashMap一樣是進(jìn)行key-value存儲(chǔ)的,數(shù)據(jù)結(jié)構(gòu)也一樣,但是HashMap不是線程安全的,HashTable是線程安全的。今天我們就來(lái)剖析一下它,因?yàn)楹虷ashMap相似,所以對(duì)比著來(lái)看。
真的想吐槽下:Hashtable 為啥不是HashTable[捂臉]

一、相同之處

  1. HashMap和HashTable數(shù)據(jù)結(jié)構(gòu)是一致的。內(nèi)部都是一個(gè)Entry<K,V>的數(shù)組。
private static class Entry<K,V> implements Map.Entry<K,V> {
        int hash;
        final K key;
        V value;
        Entry<K,V> next;

        protected Entry(int hash, K key, V value, Entry<K,V> next) {
            this.hash = hash;
            this.key =  key;
            this.value = value;
            this.next = next;
        }
}
  1. 內(nèi)部成員變量一致。loadFactor threshold modCount count(HashMap中數(shù)量用size表示)在Hashtable中均有。
  2. 同HashMap一樣,當(dāng)count>=threshold時(shí)就需要進(jìn)行擴(kuò)容了。
if (count >= threshold) {
     // Rehash the table if the threshold is exceeded
     rehash();
     ......
}

二、不同之處

  1. Hashtable初始化時(shí),默認(rèn)的容量是11,負(fù)載因子是0.75,且初始化的時(shí)候就會(huì)為Entry<K,V>數(shù)組申請(qǐng)。
public Hashtable() {
     this(11, 0.75f);
}

public Hashtable(int initialCapacity, float loadFactor) {
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal Load: "+loadFactor);

        if (initialCapacity==0)
            initialCapacity = 1;
        this.loadFactor = loadFactor;
        table = new Entry[initialCapacity];  //申請(qǐng)table數(shù)組空間
        threshold = (int)Math.min(initialCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
        initHashSeedAsNeeded(initialCapacity);
}
  1. HashMap能存儲(chǔ)key為null的情況,Hashtable不能存儲(chǔ)key為null的。
  2. 擴(kuò)容機(jī)制不同。HashMap每次resize的時(shí)候,容量會(huì)擴(kuò)容為原來(lái)的2倍,Hashtable會(huì)擴(kuò)容為原來(lái)的2倍+1(為保證奇數(shù))
  3. HashMap不是線程安全的(具體原因見(jiàn):http://m.itdecent.cn/p/c92e0e279243),Hashtable是線程安全的。實(shí)現(xiàn)的方式是通過(guò)在方法上加synchronized鎖,如下:
public synchronized V get(Object key) {
        Entry tab[] = table;
        int hash = hash(key);
        int index = (hash & 0x7FFFFFFF) % tab.length;
        for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
            if ((e.hash == hash) && e.key.equals(key)) {
                return e.value;
            }
        }
        return null;
    }

??Hashtable提供的所有方法都加上了synchronized鎖。雖然保證了線程安全,但同時(shí)我們也發(fā)現(xiàn),在每個(gè)方法上都加了這個(gè)同步鎖,在多并發(fā)的情況下,效率是很低的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容