Mi grupo de subprocesos tiene un número fijo de subprocesos. Estos hilos necesitan escribir y leer de una lista compartida con frecuencia.
Entonces, ¿qué estructura de datos (es mejor una lista, debe estar libre de monitor) en el java.util.concurrent
paquete es mejor en este caso?
java
concurrency
象 嘉 道
fuente
fuente
List
.ConcurrentModificationException
posible que no se deba a un problema de sincronización; también surge, por ejemplo, en un bucle for sobre una colección en el que intenta eliminar un elemento de la colección.Vector
?Respuestas:
La única
List
implementación enjava.util.concurrent
es CopyOnWriteArrayList . También existe la opción de una lista sincronizada como menciona Travis Webb.Dicho esto, ¿estás seguro de que necesitas que sea un
List
? Hay muchas más opciones paraQueue
s yMap
s concurrentes (y puede hacerSet
s a partir deMap
s), y esas estructuras tienden a tener más sentido para muchos de los tipos de cosas que desea hacer con una estructura de datos compartida.Para las colas, tiene una gran cantidad de opciones y cuál es la más adecuada depende de cómo necesite usarla:
fuente
CopyOnWriteArrayList
tiene la desventaja de ser muy costoso en la escritura (pero barato en las lecturas). Si está haciendo muchas escrituras, es mejor tener una Lista sincronizada o una cola.Cualquier colección de Java se puede hacer para que sea segura para subprocesos así:
List newList = Collections.synchronizedList(oldList);
O para crear una nueva lista segura para subprocesos:
List newList = Collections.synchronizedList(new ArrayList());
http://download.oracle.com/javase/6/docs/api/java/util/Collections.html#synchronizedList(java.util.List)
fuente
ConcurrentHashMap
unCollections.synchronizedMap
método aunque sí .ConcurrentHashMap
. Los detalles de la implementación de la sincronización son diferentes. el uso de lossynchronized
métodos enCollections
básicamente simplemente envuelve la clase en un monitor Java.ConcurrentHashMap
utiliza funciones de simultaneidad más inteligentes.Si el tamaño de la lista es fijo, entonces puede usar un AtomicReferenceArray . Esto le permitiría realizar actualizaciones indexadas en una ranura. Puede escribir una vista de lista si es necesario.
fuente
Es posible que desee consultar ConcurrentDoublyLinkedList escrito por Doug Lea basado en "A Practical Lock-Free Double-Linked List" de Paul Martin. No implementa la interfaz java.util.List, pero ofrece la mayoría de los métodos que usaría en una lista.
Según el javadoc:
fuente
ConcurrentLinkedQueue
utiliza una cola sin bloqueo (basada en la instrucción CAS más reciente ).fuente
List
interfaz.List.set(int index, Object element)
con ConcurrentLinkedQueue?List
métodos -específicos no serán implementables usando unQueue
(agregar / establecer en un índice específico, por ejemplo) o pueden implementarse pero serán ineficientes (obtener de un índice). Así que no creo que realmente puedas envolverlo. Dicho esto, creo que la sugerencia de aQueue
está bien ya que el OP no ha explicado realmente por qué necesitan unList
.Si el conjunto es suficiente, se puede utilizar ConcurrentSkipListSet . (Su implementación se basa en ConcurrentSkipListMap que implementa una lista de omisión ).
El costo de tiempo promedio esperado es log (n) para las operaciones de contener, agregar y eliminar; el método de tamaño no es una operación de tiempo constante.
fuente