Hashtable和HashMap之间有什么区别,如果它们在以下代码片段中抛出ConcurrentModificationException?

时间:2016-05-12 03:50:11

标签: java collections hashmap hashtable

在以下代码段中,我尝试使用Hashtable,即所谓的线程安全和HashMap。但在这两种情况下我都会ConcurrentModificationExceptionn。如果是这样,那么在线程安全的情况下HashTable优于HashMap的优势

public class multiThreadedEnv {
    static Map<Integer, String> map = new Hashtable<Integer, String>();
    //static Map<Integer, String> map = new HashMap<Integer, String>();

    static{
        map.put(1, "One");
        map.put(2, "Two");
        map.put(3, "Three");
        map.put(4, "Four");
        map.put(5, "Five");
    }

    public static void main(String[] args) {
        Thread t1 = new Thread(){
            public void run() {
                Iterator itr= map.entrySet().iterator();
                while(itr.hasNext()){
                    Entry<String,String> entry=(Entry<String, String>) itr.next();
                    System.out.println(entry.getKey()+" , "+entry.getValue());
                    itr.remove();
                    Thread.sleep(2000);
                }
            }
        };

        Thread t2= new Thread(){
            public void run() {
                Iterator itr= map.entrySet().iterator();
                while(itr.hasNext()) {
                    Entry<String,String> entry=(Entry<String, String>) itr.next();
                    System.out.println(entry.getKey()+" , "+entry.getValue());
                    itr.remove();
                    Thread.sleep(2000);
                }
            }
        };

        t1.start();
        t2.start();
    }
}

1 个答案:

答案 0 :(得分:1)

Hashtable已同步,阻止两个线程同时访问它。

  

从Java 2平台v1.2开始,该类被改进以实现Map接口,使其成为Java Collections Framework的成员。与新的集合实现不同,Hashtable是同步的。如果不需要线程安全实现,建议使用HashMap代替Hashtable。如果需要线程安全的高度并发实现,则建议使用ConcurrentHashMap代替Hashtable

HashMap未同步。

  

请注意,此实现未同步。如果多个线程同时访问哈希映射,并且至少有一个线程在结构上修改了映射,则必须在外部进行同步。 (结构修改是添加或删除一个或多个映射的任何操作;仅更改与实例已包含的键关联的值不是结构修改。)

同步不会阻止ConcurrentModificationException,因为他们都说

  

所有这类&#34;集合视图方法返回的迭代器&#34; fail-fast :如果在创建迭代器之后的任何时候对[Hashtable / map]进行结构修改,除了通过迭代器自己的remove方法之外,迭代器将抛出ConcurrentModificationException

请注意,单个线程可以通过直接更新Hashtable / HashMap同时迭代它来导致ConcurrentModificationException。它并不需要多线程来违反这条规则。

ConcurrentHashMap说:

  

Iterators和Enumerations在迭代器/枚举的创建时或之后的某个时刻返回反映哈希表状态的元素。他们抛出ConcurrentModificationException。但是,迭代器设计为一次只能由一个线程使用。

因此,HashMap对单线程访问很有用 Hashtable对于多线程访问很有用,只要他们不需要迭代地图。
ConcurrentHashMap允许多个线程进行更新和迭代。