framework - hashset java
¿La envoltura inmodificable para las colecciones de Java las hace seguras? (9)
Necesito hacer una lista ArrayList de ArrayLists segura. Tampoco puedo permitir que el cliente realice cambios en la colección. ¿La envoltura no modificable la hará segura o necesito dos envoltorios en la colección?
Al mirar el origen de Colecciones, parece que Sin modificaciones no lo sincroniza.
static class UnmodifiableSet<E> extends UnmodifiableCollection<E>
implements Set<E>, Serializable;
static class UnmodifiableCollection<E> implements Collection<E>, Serializable;
los wrappers de clase sincronizados tienen un objeto mutex en ellos para hacer las partes sincronizadas, por lo que parece que necesita usar ambos para obtener ambos. ¡O hazlo tu mismo!
Creo que debido a que el contenedor UnmodifiableList almacena ArrayList en un campo final, todos los métodos de lectura en el contenedor verán la lista tal como estaba cuando se creó el contenedor, siempre y cuando la lista no se modifique después de crear el contenedor y como siempre que las ArrayLists mutables dentro del contenedor no se modifiquen (lo que el envoltorio no puede proteger).
Depende. El contenedor solo evitará cambios en la colección que envuelve, no en los objetos de la colección. Si tiene un ArrayList de ArrayLists, la Lista global así como también cada una de sus listas de elementos deben ser incluidas por separado, y también puede tener que hacer algo para el contenido de esas listas. Finalmente, debe asegurarse de que los objetos de la lista original no se modifiquen, ya que el contenedor solo evita los cambios a través de la referencia del contenedor, no al objeto original.
NO es necesario el contenedor sincronizado en este caso.
El contenedor inmodificable solo evita cambios en la estructura de la lista a la que se aplica. Si esta lista contiene otras listas y tiene hilos que intentan modificar estas listas anidadas, entonces no estará protegido contra los riesgos de modificación simultáneos.
Estará seguro para subprocesos si la vista no modificable se publica con seguridad, y el original modificable nunca se modifica (¡incluidos todos los objetos recursivamente incluidos en la colección!) Después de la publicación de la vista no modificable.
Si desea seguir modificando el original, puede crear una copia defensiva del gráfico objeto de su colección y devolver una vista inmodificable de eso, o usar una lista inherentemente segura para subprocesos para comenzar, y devolver una vista no modificable de ese.
No puede devolver una lista no modificable (synchonizedList (theList)) si aún tiene la intención de acceder a la lista no sincronizada posteriormente; si el estado mutable se comparte entre varios subprocesos, todos los subprocesos se deben sincronizar en los mismos bloqueos cuando acceden a ese estado.
Esto es necesario si:
- Todavía hay una referencia a la lista modificable original.
- La lista posiblemente se accederá a través de un iterador.
Si tiene la intención de leer desde ArrayList solo por índice, puede suponer que es seguro para subprocesos.
En caso de duda, elija el contenedor sincronizado.
No estoy seguro si entendí lo que está tratando de hacer, pero diría que la respuesta en la mayoría de los casos es "No".
Si configura una ArrayList de ArrayList y ambas, las listas externa e interna nunca se pueden cambiar después de la creación (y durante la creación solo un subproceso tendrá acceso a las listas internas y externas), es probable que sean subprocesadas por un reiniciador (si ambos , las listas externas e internas están envueltas de tal manera que su modificación es imposible). Es muy probable que todas las operaciones de solo lectura en ArrayLists sean seguras para subprocesos. Sin embargo, Sun no garantiza que sean seguros para subprocesos (ni tampoco para operaciones de solo lectura), por lo que aunque funcione en este momento, podría fallar en el futuro (si Sun crea un almacenamiento interno de datos para un acceso más rápido). ejemplo).
Sobre un tema relacionado: he visto varias respuestas que sugieren el uso de la recolección sincronizada para lograr la seguridad del hilo. El uso de la versión sincronizada de una colección no lo hace "seguro para subprocesos", aunque cada operación (inserción, recuento, etc.) está protegida por mutex al combinar dos operaciones, no hay garantía de que se ejecuten atómicamente. Por ejemplo, el siguiente código no es seguro para subprocesos (incluso con una cola sincronizada):
if(queue.Count > 0)
{
queue.Add(...);
}
Un objeto inmutable es, por definición, seguro para subprocesos (suponiendo que nadie conserva las referencias a las colecciones originales), por lo que la sincronización no es necesaria.
Envolver el ArrayList externo utilizando Collections.unmodifiableList () evita que el cliente cambie su contenido (y lo hace seguro para subprocesos), pero las ArrayLists internas todavía son mutables.
Envolver las ArrayLists internas utilizando Collections.unmodifiableList () también evita que el cliente cambie sus contenidos (y, por lo tanto, hace que sean segmentados), que es lo que necesita.
Háganos saber si esta solución causa problemas (gastos generales, uso de memoria, etc.); otras soluciones pueden ser aplicables a su problema. :)
EDITAR: por supuesto, si las listas se modifican, NO son seguras para subprocesos. Supuse que no se realizarían más ediciones.