Hashtable是线程安全的,那么Hashtable是如何实现线程安全的呢?有了上面的介绍,我们直接从源码中分析其线程安全性:
public synchronized V put(K key, V value) {
// 保证value值不为空,此处省略其代码 ..
// 保证key是不重复的,此处省略其代码 ..
//查过阈值则扩容,此处省略
// Creates the new entry.
Entry<K,V> e = tab[index]; tab[index] = new Entry<>(hash, key, value, e); count++; return null;
}
通过源码可以很明显看到其put方法使用synchronized关键字,在线程中这是实现线程安全的一种方式,所以Hashtable是线程安全的。
当一个线程访问HashTable的同步方法时,其他线程如果也要访问同步方法,会被阻塞住。举个例子,当一个线程使用put方法时,另一个线程不但不可以使用put方法,连get方法都不可以,好霸道啊!!!so~~,效率很低,现在基本不会选择它了。
Hashtable的测试案例:
下面使用一段测试代码验证Hashtable的线程安全:
Hashtable<Integer, String> hashTable = new Hashtable<Integer, String>(); final Hashtable<Integer, String> hashTable_back = hashTable; Thread t3 = new Thread(){ public void run(){ for (int i = 0; i < 20; i++) { hashTable_back.put(i, String.valueOf(i)); } } }; Thread t4 = new Thread(){ public void run(){ for (int i = 20; i < 40; i++) { hashTable_back.put(i, String.valueOf(i)); } } }; t3.start(); t4.start(); //放完数据后,从map中取出数据,如果map是线程安全的,那么取出的entry应该和放进去的一一对应 new Handler().postDelayed( new Runnable() { @Override public void run() { for (int i = 0; i < 20; i++) { showlog(i + "=" + hashTable_back.get(i)); } } }, 1000);
最后得到的输出结果是这样的:
OK,再次说明Hashtable是线程安全的。