zoukankan      html  css  js  c++  java
  • Hashtable是同步的。 如果不需要线程安全的实现,建议使用HashMap代替Hashtable 。 如果需要线程安全的并发实现,那么建议使用ConcurrentHashMap代替Hashtable

    打开Hashtable的源码可以看见

    1、Hashtable底层存放数据的其实是他的一个内部类的数组,在创建Hashtable实例的时候,需要指定这个数组的长度,默认是11,源码如下:

    //无参构造方法
    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是具体放值的数组,设置长度是传入参数initialCapacity,期默认值是11
            //Entity是一个被私有了的内部类
            table = new Entry<?,?>[initialCapacity];
            threshold = (int)Math.min(initialCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
        }
     private static class Entry<K,V> implements Map.Entry<K,V> {
            final 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;
            }
    
            @SuppressWarnings("unchecked")
            protected Object clone() {
                return new Entry<>(hash, key, value,
                                      (next==null ? null : (Entry<K,V>) next.clone()));
            }
    
            // Map.Entry Ops
    
            public K getKey() {
                return key;
            }
    
            public V getValue() {
                return value;
            }
    
            public V setValue(V value) {
                if (value == null)
                    throw new NullPointerException();
    
                V oldValue = this.value;
                this.value = value;
                return oldValue;
            }
    
            public boolean equals(Object o) {
                if (!(o instanceof Map.Entry))
                    return false;
                Map.Entry<?,?> e = (Map.Entry<?,?>)o;
    
                return (key==null ? e.getKey()==null : key.equals(e.getKey())) &&
                   (value==null ? e.getValue()==null : value.equals(e.getValue()));
            }
    
            public int hashCode() {
                return hash ^ Objects.hashCode(value);
            }
    
            public String toString() {
                return key.toString()+"="+value.toString();
            }
        }
    Entry 类源码

    2、因为Hashtable是通过Entity数组存值的,且Entity有一个属性是专门放其数组中下一个值的Entity对象的,所以,查找起来更快,查找方法源码如下:

    public synchronized V get(Object key) {
            Entry<?,?> tab[] = table;
            // 计算出key对应的hash值
            int hash = key.hashCode();
             // 使用key对应hash值算出一个数值来,使其在数组数组长度范围内,用来作为查找开的的索引
            int index = (hash & 0x7FFFFFFF) % tab.length;
            for (Entry<?,?> e = tab[index] ; e != null ; e = e.next) {
                if ((e.hash == hash) && e.key.equals(key)) {
                    return (V)e.value;
                }
            }
            return null;
        }

    3、通过put方法源码看到存值时只对value做了非空校验,且如果key对应的位置已经存有值,将会覆盖后返回老值

    4、通过源码看如果找到了返回老值,没找到,返回null。

    5、其线程安全的实现方式是在每个操作方法上都添加了synchronized同步锁,是的对其进行操作的时候要有获得锁和释放锁的操作,所以如果不需要线程安全最好不要用他。

    6、java1.5之后,java为线程安全key&value集合提供了一个ConcurrentHashMap,它的实现思路和HashTable基本类似,不过在其基础上又做了很多优化。例如,他的同步锁不是加载方法上的,而是加在代码块上的,通过key计算hashcode的时候除了调用object的hashcode方法外还做了(h ^ (h >>> 16)) & HASH_BITS;位移后的与操作。

    7、通过debug的时候发现,在实际使用hashTable时,java给我们加了层代理,而且不止java加了,不同的运行环境也有不同的处理。

     打开代理方法都是被native关键字修饰了。而期创建的hashTable对象也是其子类Properties的对象

  • 相关阅读:
    Two strings CodeForces
    Dasha and Photos CodeForces
    Largest Beautiful Number CodeForces
    Timetable CodeForces
    Financiers Game CodeForces
    AC日记——整理药名 openjudge 1.7 15
    AC日记——大小写字母互换 openjudge 1.7 14
    AC日记——将字符串中的小写字母换成大写字母 openjudge 1.7 13
    AC日记——加密的病历单 openjudge 1.7 12
    AC日记——潜伏着 openjudge 1.7 11
  • 原文地址:https://www.cnblogs.com/tianhaichao/p/12214497.html
Copyright © 2011-2022 走看看