程序员

Java集合-HashTable

2017-08-17  本文已影响33人  懒懒惰惰

之前分析过HashMap的结构,接下来简单的分析一下HashTable的数据结构和线程安全的实现。

HashTable !

HashTable实现上与HashMap实现的数据结构相似,先看HashTable定义:

public class Hashtable<K,V>
    extends Dictionary<K,V>
    implements Map<K,V>, Cloneable, java.io.Serializable {

它实现了Map接口,与HashMap不一样的是,他继承了Dictionary。那么接下来看一下他的主要成员变量:

private transient Entry<K,V>[] table;
private transient int count;
private int threshold;
private float loadFactor;

与HashMap类似,他拥有一个hash的表table数组,同时定义了装载因子loadFactor,初始化桶容量threshold,接下来看一下HashTable重写的Entry:

private static class Entry<K,V> implements Map.Entry<K,V> {
    int hash;
    final K key;
    V value;
    Entry<K,V> next;
    ...
}

与HashMap类似的他将Entry定义为一个存储key-map的链表结构。那么我们可以继续仿照HashMap去理解HashTable的结构。

接下来,我们看一下HashTable中的put方法:

public synchronized V put(K key, V value) {
    // Make sure the value is not null
    if (value == null) {
        throw new NullPointerException();
    }

    // Makes sure the key is not already in the hashtable.
    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)) {
            V old = e.value;
            e.value = value;
            return old;
        }
    }

    modCount++;
    if (count >= threshold) {
        // Rehash the table if the threshold is exceeded
        rehash();

        tab = table;
        hash = hash(key);
        index = (hash & 0x7FFFFFFF) % tab.length;
    }

    // Creates the new entry.
    Entry<K,V> e = tab[index];
    tab[index] = new Entry<>(hash, key, value, e);
    count++;
    return null;
}

第一眼看上去,好长,而且在一个方法内实现了大部分的逻辑,可以看出,HashTable在实现数据结构层面上没有HashMap的精炼,算法层面上也没有HashMap写的优。一部分原因是这部分代码实现在JDK1.0中,另一方面,是为了保持操作的原子性,保证线程安全。可以看到,HashTable在实现线程安全方面,通过将读写操作代码整合在一个方法中,通过synchronized来达到线程互斥,保证线程安全。
那么看一下HashTable中还有哪些通过synchronized声明的方法:

synchronized void                clear()
synchronized Object              clone()
synchronized boolean             contains(Object value)
synchronized boolean             containsKey(Object key)
synchronized boolean             containsValue(Object value)
synchronized Enumeration<V>      elements()
synchronized Set<Entry<K, V>>    entrySet()
synchronized boolean             equals(Object object)
synchronized V                   get(Object key)
synchronized int                 hashCode()
synchronized boolean             isEmpty()
synchronized Set<K>              keySet()
synchronized Enumeration<K>      keys()
synchronized V                   put(K key, V value)
synchronized void                putAll(Map<? extends K, ? extends V> map)
synchronized V                   remove(Object key)
synchronized int                 size()
synchronized String              toString()
synchronized Collection<V>       values()

通过分析put方法大致发现了HashTable在实现线程安全方面采取了一些有别于HashMap的方式,其他的方法可以大致参考HashMap的解释,就懒一下,不分析了。

上一篇 下一篇

猜你喜欢

热点阅读