¿Cómo puedo crear una instancia de Lista concurrente, donde puedo acceder a elementos por índice? ¿El JDK tiene alguna clase o método de fábrica que pueda usar?
java
list
concurrency
AlikElzin-kilaka
fuente
fuente
List
que el original específicamente dice que es un requisito que se considera vandalismo. Un moderador ya bloqueó la pregunta debido a las personas que se quejan de que las respuestas no responden a esa versión vandalizada de la pregunta.locked
/closed
/ comentario anteriorRespuestas:
Hay una implementación de lista concurrente en java.util.concurrent . CopyOnWriteArrayList en particular.
fuente
Si no le importa tener acceso basado en índices y solo desea las características de preservación del orden de inserción de una Lista, puede considerar un java.util.concurrent.ConcurrentLinkedQueue . Como implementa Iterable, una vez que haya terminado de agregar todos los elementos, puede recorrer los contenidos utilizando la sintaxis mejorada:
fuente
:
) se llama foreach: docs.oracle.com/javase/1.5.0/docs/guide/language/foreach.htmlPuedes usar Collections.synchronizedList (List) si todo lo que necesitas es una simple sincronización de invocación:
fuente
synchronizedList
es "sincronizado" pero no "concurrente". Una cuestión fundamental es que muchas operaciones de Lista, que están basadas en índices, no son atómicas y deben formar parte de una construcción de exclusión mutua más amplia.Vector
es más sencillo queCollections.synchronizedList(new ArrayList<Object>())
.Debido a que el acto de adquirir la posición y obtener el elemento de la posición dada, naturalmente requiere cierto bloqueo (no puede hacer que la lista tenga cambios estructurales entre esas dos operaciones).
La idea misma de una colección concurrente es que cada operación por sí sola es atómica y se puede hacer sin bloqueo / sincronización explícitos.
Por lo tanto, obtener el elemento en la posición
n
de unaList
operación atómica dada no tiene mucho sentido en una situación en la que se anticipa el acceso concurrente.fuente
Tienes estas opciones:
Collections.synchronizedList()
: Se puede envolver cualquierList
aplicación (ArrayList
,LinkedList
o una lista tercera parte). El acceso a todos los métodos (lectura y escritura) estará protegido mediantesynchronized
. Al usariterator()
o mejorar el bucle, debe sincronizarlo manualmente; mientras itera, otros hilos están completamente bloqueados incluso de la lectura. También puede sincronizar por separado para cada unahasNext
y lasnext
llamadas, pero luegoConcurrentModificationException
es posible.CopyOnWriteArrayList
: es costoso modificarlo, pero esperar para leerlo. Los iteradores nunca arrojanConcurrentModificationException
, devuelven una instantánea de la lista en el momento de la creación del iterador, incluso si la lista es modificada por otro hilo mientras itera. Útil para listas actualizadas con poca frecuencia.addAll
Se prefieren las operaciones masivas como las actualizaciones: la matriz interna se copia con menos frecuencia.Vector
: muy parecidosynchronizedList
, pero la iteración también está sincronizada. Sin embargo, los iteradores pueden lanzarConcurrentModificationException
, si el vector es modificado por otro hilo mientras itera.Otras opciones:
Collections.unmodifiableList()
: sin bloqueo, seguro para subprocesos, pero no modificableQueue
oDeque
podría ser una alternativa si solo agrega / elimina al final de la lista e itera la lista. No hay acceso por índice ni adición / eliminación en lugares arbitrarios. Tienen múltiples implementaciones concurrentes con un mejor rendimiento y un mejor acceso concurrente, pero está fuera del alcance de esta pregunta. También puede echar un vistazo a JCTools , que contienen implementaciones de cola más eficaces especializadas para un solo consumidor o un solo productor.fuente
CopyOnWriteArrayList es una alternativa concurrente de la lista sincronizada implementa la interfaz List y es parte del paquete java.util.concurrent y es una colección segura para subprocesos.
CopyOnWriteArrayList es a prueba de fallas y no arroja ConcurrentModificationException cuando CopyOnWriteArrayList subyacente se modifica durante la iteración, use una copia separada de ArrayList.
Esto suele ser demasiado costoso porque la matriz de copia involucra cada operación de actualización, se creará una copia clonada. CopyOnWriteArrayList es la mejor opción solo para operaciones de lectura frecuente.
http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/CopyOnWriteArrayList.html
https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/CopyOnWriteArrayList.html
fuente