Problema con iteración
jueves, noviembre 8, 2012 at 9:26AM
choces

Se sabe que los iteradores no son thread-safe. Lo mismo pueden lanzar una ConcurrentModificationException, que mostrar resultados inconsistentes, en un entorno multitarea.

Me he encontrado con el siguiente problema: 

   @Override
    public List<String> getCovers(final List<Release> releases) {
        final List<String> coversURL = new ArrayList<>(2 * releases.size());
        for (final Iterator<Release> it = releases.iterator(); it.hasNext();) {
            coversURL.add(it.next().getThumb());
        }
        return coversURL;
    }
Este método forma parte de una clase que funciona como Service Provider, y al que se accede mediante un interface.
La cuestión es que si una tarea paralela modifica la lista releases, mientras que otra diferente ejecuta este método, se producirá o una excepción (lo más probable) o una inconsistencia extraña.
De momento, la única solución que he encontrado sería:
  @Override
    public List<String> getCovers(final List<Release> releases) {
        final ArrayList<Release> localReleases = new ArrayList<>(releases);
        final List<String> coversURL = new ArrayList<>(2 * localReleases.size());
        for (final Iterator<Release> it = localReleases.iterator(); it.hasNext();) {
            coversURL.add(it.next().getThumb());
        }
        return coversURL;
    }
que realiza una "copia defensiva" del parámetro, para forzar la iteración sobre la variable local. El objeto es evitar una excepción, porque si el parámetro cambia, los resultados no serán consistentes con el cambio.
¿Hay otras soluciones?.

 

Article originally appeared on javaHispano (http://www.javahispano.org/).
See website for complete article licensing information.