美文网首页程序员
Java集合-HashTable

Java集合-HashTable

作者: 懒懒惰惰 | 来源:发表于2017-08-17 10:15 被阅读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的解释,就懒一下,不分析了。

    相关文章

      网友评论

        本文标题:Java集合-HashTable

        本文链接:https://www.haomeiwen.com/subject/jrlgrxtx.html