2016-05-12 23 views
0

在以下代码片段中,我尝试了所谓的线程安全HashtableHashMap。但在两种情况下,我得到ConcurrentModificationExceptionn。如果是这样,那么什么是线程安全Hashtable和HashMap之间有什么区别,如果两者在下面的代码片段中抛出ConcurrentModificationException?

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(); 
    } 
} 
+0

“Hashtable”本质上被弃用的全部原因是它让你思考你有没有线程安全。 –

+0

可能重复的[如何调试ConcurrentModificationException?](http://stackoverflow.com/questions/840165/how-to-debug-concurrentmodificationexception) – Raedwald

+0

@LouisWasserman当你说'Hashtable'和“deprecated”时要小心当我在听力范围内的时候判刑。 :-) –

回答

1

Hashtable的情况下HashTableHashMap的优势是同步的,防止两个线程同时访问它。

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

HashMap不同步。

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

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

所有的此类的“collection视图方法”所返回的迭代器都是快速失败的:如果[哈希表/图]在任何时间创建迭代器后结构修饰,除了通过迭代器自己的012之外方法,迭代器将抛出ConcurrentModificationException

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

ConcurrentHashMap说:

迭代和枚举返回元件反射在或自创建迭代器/枚举的哈希表的在某一时刻的状态。他们做不是 throw ConcurrentModificationException。但是,迭代器被设计为一次只能由一个线程使用。

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

相关问题