Ayuda con ConcurrentModificationException

Hola estimados...

He estado trabajando con hilos últimamente...y llegué a un punto en donde dentro de mi lógica me da la exception "ConcurrentModificationException"...buscando en la documentacion (http://docs.oracle.com/javase/7/docs/api/java/util/ConcurrentModificatio...) entendí por qué se da.

Estoy manejando lo siguiente:

  clase A
   ....
  private static HashMap<String, ThreadResult> objHasMapResult = new HashMap<String,ThreadResult>();
   ....

Este hashMap lo uso para ir guardando un objeto de resultado que modifica cada tarea:

  método call() de cada tarea:
  ....
  @Override
        public ThreadResult call()
        {
                ControlList controlList = ControlList.getInstance();
                this.objResult = new ThreadResult();
                this.objResult.setIdThread(this.name);
                try
                {                      
                        Thread.currentThread().setName(this.name);     
                        System.out.printf("INICIO: "+Thread.currentThread().getName() +".\n");
                        if(this.listFutures.size()>0)
                        {
                                for(Future<ThreadResult> objFuture : this.listFutures)
                                {                                                              
                                        ThreadResult objResultado = objFuture.get();
                                       
                                        if(objResult.getInterruptedEx() != null){
                                                this.objResult.setIdThreadPadre(objResultado.getIdThreadPadre());
                                                throw new InterruptedException(objResultado.getInterruptedEx());                                       
                                        }
                                        else if(objResult.getExecutionEx()!=null) {
                                                this.objResult.setIdThreadPadre(objResultado.getIdThreadPadre());
                                            throw new ExecutionException(objResultado.getExecutionEx(),new Throwable());                                       
                                        }
                                        else if(objResult.getCancellationEx()!=null) {
                                                this.objResult.setIdThreadPadre(objResultado.getIdThreadPadre());
                                                throw new CancellationException(objResultado.getCancellationEx());
                                        }              
                                }
                        }
                        Thread.sleep(sleepTime);
                        System.out.println("FIN: "+Thread.currentThread().getName()+". Time: " + (System.currentTimeMillis()-time));
                        this.objResult.setExito(true);
                }
                catch(InterruptedException e){
                        this.objResult.setInterruptedEx(e.getMessage());
                        this.objResult.setDetalle(e.getMessage());
                        this.objResult.setExito(false);

                } catch (ExecutionException e) {
                        this.objResult.setExecutionEx(e.getMessage());
                        this.objResult.setDetalle(e.getMessage());
                        this.objResult.setExito(false);
                }catch(CancellationException e) {
                        this.objResult.setCancellationEx(e.getMessage());
                        this.objResult.setDetalle(e.getMessage());
                        this.objResult.setExito(false);
                }
                synchronized (this) {
                        controlList.getObjHasMapResult().put(this.name, objResult);
                }
               
                return this.objResult;
        }

entonces cuando quiero desde mi programa principal iterar sobre el hashMap, lanza la exception.

               //Thread.sleep(10000); cuando agrego este sleep...se espera a que todos los hilos escriban en el HashMap, y no se lanza la exception. Pero cuando lo quito, se da la exception porque se trata de iterar cuando se está trabajando sobre el map.              

               Iterator it2 = controlList.getObjHasMapResult().keySet().iterator();
                while(it2.hasNext())    {
                       
                        String hilo = (String) it2.next();
                        ThreadResult threadR = controlList.getObjHasMapResult().get(hilo);                     
                       
                        if(threadR.isExito()){
                                System.out.println(threadR.getIdThread()+" EXITO");
                        }
                        else{
                                System.out.println(threadR.getIdThread()+" ERROR");
                        }
                }

Necesito que cada cierto tiempo se vaya revisando el map..u otra estructura...de modo de conocer los estados de cada tarea y tomar decisiones.

Gracias desde ya.

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.

ConcurrentHashMap

 

De acuerdo con la documentación, las operaciones de java.util.HashMap no son thread-safe.

Es posible obtener una vista sincronizada con:

Map m = Collections.synchronizedMap(new HashMap(...));

No obstante, java.util.concurrent.ConcurrentHashMap tiene un mejor rendimiento, aunque no permite claves ni valores nulos.

~~~