2011-05-20 7 views
12

Tengo un ArrayList que se almacenará en caché y se compartirá entre varios subprocesos indefinidamente. Las operaciones incluyen frecuentes adiciones y eliminaciones, más iteraciones ocasionales.alternativa a CopyOnWriteArrayList para escrituras frecuentes, iteración ocasional

Los ArrayList vidas en una clase contenedora que gestiona el acceso al mismo:

public class MyListWrapper<T> implements Iterable<T> { 

    private List<T> innerList = new ArrayList<T>(); 

    public Iterator<T> iterator() { 
     return innerList.listIterator(); 
    } 

    public void add(T element) { 
     innerList.add(element); 
     //app-specific logic 
    } 

    //remove(T), etc in the same pattern... 
} 

Actualmente estoy haciendo los preparativos para la seguridad de los subprocesos. Al principio, CopyOnWriteArrayList me pareció la mejor respuesta, pero su rendimiento me preocupa, ya que las modificaciones se realizarán con más frecuencia que cualquier otra cosa.

¿Sería un cambio manual en la clase contenedora como este ser una mejor alternativa ?:

public Iterator<T> iterator() { 
    return new ArrayList<T>(innerList).listIterator(); 
} 

//plus concurrency tweaks for any non-atomic modifications to innerList 

Por favor, me ayudan a encontrar el mejor enfoque.

Respuesta

7

Puede intentar usar un Collections.newSetFromMap(new ConcurrentHashMap<T, Boolean>()); Esto le dará un conjunto de hash simultáneo que le dará cerca de O (1) agregar y eliminar.

+0

Excelente, esto es exactamente lo que necesitaba. +1 por enseñarme algo. Gracias –

+0

Su iterador es seguro para subprocesos, por lo que no necesita sincronizar y no necesita tomar una copia. –

+0

En java 1.8 Supongo que ese método ha sido renombrado Collections.newSetFromMap –

4

Una posibilidad es utilizar ConcurrentLinkedQueue si puede vivir con la interfaz Queue en lugar de la Lista. Yo diría que se pueden satisfacer más casos de uso de los esperados con una cola. Una ventaja clave de List es el acceso aleatorio (basado en el índice), pero en una situación concurrente el acceso aleatorio no es necesario ni deseable.

ConcurrentLinkedQueue es una excelente implementación concurrente de Queue.

+0

+1 Me di cuenta desde que hice esta pregunta que el acceso aleatorio no era importante, y que no era necesario utilizar una lista en primer lugar. –

Cuestiones relacionadas