2016-05-12 2 views
0

В следующем фрагменте кода я попробовал как с Hashtable, который называется потокобезопасным, так и HashMap. Но в обоих случаях я получаю ConcurrentModificationExceptionn. Если это так, то, что преимущества HashTable над HashMap в случае безопасности потокаВ чем разница между 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' была по существу устаревшей, заключалась в том, что она сделала вас _think_ у вас была безопасность потоков, когда вы этого не сделали. –

+0

Возможный дубликат [Как отладить ConcurrentModificationException?] (Http://stackoverflow.com/questions/840165/how-to-debug-concurrentmodificationexception) – Raedwald

+0

@LouisWasserman Будьте осторожны, когда вы говорите «Hashtable» и «устарели» в том же когда я в пределах слышимости. :-) –

ответ

1

Hashtable синхронизирован, предотвращая два потока от доступа к нему в то же самое время.

На платформе Java v1.2 2, этот класс был модернизирован для реализации интерфейса Map, что делает его членом Framework Java Collections. В отличие от новых реализаций коллекции, синхронизируется Hashtable. Если поточно-безопасная реализация не требуется, рекомендуется использовать HashMap вместо Hashtable. Если требуется поточнобезопасная высококонкурентная реализация, тогда рекомендуется использовать ConcurrentHashMap вместо Hashtable.

HashMap не синхронизирован.

Обратите внимание, что эта реализация не синхронизирована. Если несколько потоков обращаются к карте хешей одновременно, и по крайней мере один из потоков изменяет структуру структурно, она должна быть синхронизирована извне. (Структурная модификация является любая операция, которая добавляет или удаляет один или несколько отображений, просто изменяя значение, связанное с ключом, который экземпляр уже содержит не структурная модификация.)

синхронизация не мешает ConcurrentModificationException, потому что они оба говорят:

итераторов возвращаемые все «методы просмотра коллекции» этого класса являются отказоустойчивость быстро: если [Hashtable/карта] конструктивно изменен в любое время после создания итератора, в любом случае, кроме как через собственный 012 итератора, итератор будет кидать ConcurrentModificationException.

Обратите внимание, что один поток может вызвать ConcurrentModificationException путем обновления Hashtable/HashMap непосредственно при его повторении. Для нарушения этого правила не требуется многопоточность.

ConcurrentHashMap говорит:

итераторы и Перечисления элементы возвратные, отражающие состояние хэш-таблицы в какой-то точке или с момента создания итератора/перечисления. Они делают не throw ConcurrentModificationException. Однако итераторы предназначены для использования только по одному потоку за раз.

Так, HashMap полезен для однопоточного доступа.
Hashtable полезен для многопоточного доступа, если им не требуется итерировать карту.
ConcurrentHashMap позволяет обновлять и итерации несколькими потоками.

Смежные вопросы