2014-01-31 3 views
0

Я получаю одновременное исключение модификации при выполнении следующего кода:java.util.concurrent.ExecutionException: java.util.ConcurrentModificationException

MyMap является глобальной переменной и является HashMap

Callable<String> task = new Callable<String>() { 
    @Override 
    public String call() {   
     mymap.put("myid", "id2"); 
     mymap.put("myname", "joe"); 
     String id = mymap.get("myid"); 
     System.out.println("id is: "+ id+ ", mymap BEFORE: "+mymap.toString()); 
     mymap.remove("myid"); 
     System.out.println("id is: "+ id+ ", mymap AFTER: "+mymap.toString()); 
     return id; 
    } 
}; 

List<Callable<String>> tasks = Collections.nCopies(7, task); 
ExecutorService executorService = Executors.newFixedThreadPool(7); 
List<Future<String>> futures = executorService.invokeAll(tasks); 
List<String> resultList = new ArrayList<String>(futures.size()); 

for (Future<String> future: futures){ 
    resultList.add(future.get()); 
} 

исключение линиями:

resultList.add(future.get()); 

и

System.out.println("id is: "+ id+ ", mymap AFTER: "+mymap.toString()); 

Однако, если я пытаюсь

System.out.println("srcNode AFTER: "+srcNode.toString()+ ", id: "+id); 

вместо ошибка, кажется, исчезает. Какие-нибудь подсказки о том, что происходит?

+0

Что такое Mymap? – assylias

+0

его HasHMap () ... спасибо, что указали это. – chapstick

+0

@chapstick u r используя многопоточность ?? – Kick

ответ

0

HashMap не является потокобезопасным.

Если вы хотите синхронизировать (то есть потокобезопасным) карту, используйте Collections.synchronizedMap() обернуть HashMap:

http://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#synchronizedMap%28java.util.Map%29

Или использовать ConcurrentHashMap:

http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentHashMap.html

+0

Не является частью [concurrent] (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentMap.html) коллекции коллекции? Они потоки безопасны? –

+0

@MichaelT Вы правы –

+0

Кстати, [SkipList] (http: // ru.wikipedia.org/wiki/Skip_list) (структура данных поддержки для ConcurrentSkipListMap) является моей любимой структурой данных, когда вы садитесь и думаете о том, как это работает и что это значит. –

0

Поскольку Есть несколько нити, изменяющие один и тот же экземпляр - вы получаете эту ошибку. Что касается,

почему один пункт заявление работает, а не другой

Тем не гарантируется, чтобы обеспечить тот же результат каждый раз. Возможно, что если вы будете выполнять эту программу много раз, вы получите другой результат (без исключения, исключения в другой строке и т. Д.).

Пример - Я только что выполнил эту программу 3 раза, исполнение было успешным 2 раза и в третий раз получило параллельное исключение.

В заключение не гарантируется порядок или сроки выполнения потоков. Во избежание этих ошибок используйте синхронизацию или HashTable, которая является потокобезопасной - однако она стоит за счет производительности. Кроме того, если mymap, объявленный как локальная переменная, будет работать, поскольку каждый поток будет иметь свою собственную копию локальной переменной, но я предполагаю, что это переменная экземпляра по какой-либо причине.

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