Pregunta

Necesito hacer un ArrayList de ArrayLists seguro para subprocesos.Yo también no puede tener el cliente de hacer cambios a la colección.Se la inmodificable contenedor de hacer que sea seguro para subprocesos o necesito dos contenedores en la colección?

¿Fue útil?

Solución

Depende.El contenedor sólo de evitar cambios en la colección que envuelve, no a los objetos de la colección.Si usted tiene un ArrayList de ArrayLists, la Lista global así como cada uno de sus elemento Listas deben ser envueltos por separado, y usted también puede tener que hacer algo por el contenido de las listas.Por último, usted tiene que asegurarse de que la lista original de los objetos no cambian, ya que el contenedor sólo evita los cambios a través de la envoltura de referencia, no al objeto original.

Usted NO necesita la sincronizado contenedor en este caso.

Otros consejos

En un tema relacionado - he visto varias respuestas de lo que sugiere el uso sincronizado de la colección con el fin de lograr la seguridad de los subprocesos.Usando versión sincronizada de una colección que no lo hace "thread safe" - aunque cada operación (insertar, contar, etc.) está protegido por la mutua cuando la combinación de dos operaciones, no hay ninguna garantía de que iban a ejecutar de forma atómica.Por ejemplo, el siguiente código no es seguro para subprocesos (incluso con una sincronizada de la cola):

if(queue.Count > 0)
{
   queue.Add(...);
}

La inmodificable contenedor sólo impide que los cambios en la estructura de la lista que se aplica.Si esta lista contiene otras listas y tiene hilos tratando de modificar estas listas anidadas, entonces usted no está protegido contra la simultánea modificación de los riesgos.

A partir de la observación de las Colecciones de la fuente, parece Inmodificable ¿ no hacer sincronizado.

static class UnmodifiableSet<E> extends UnmodifiableCollection<E>
                 implements Set<E>, Serializable;

static class UnmodifiableCollection<E> implements Collection<E>, Serializable;

el sincronizado de contenedores de clase tienen un objeto mutex para hacer las partes sincronizadas, por lo que parece que usted necesita para utilizar ambos para obtener ambos.O rollo de su propio!

Creo que porque el UnmodifiableList contenedor almacena el ArrayList a un campo final, cualquier métodos de lectura en el contenedor va a ver la lista de como era cuando el contenedor se construyó tan largo como la lista no se modifica después de que se crea el contenedor, y mientras lo mutable ArrayLists en el interior del contenedor, no se modifican (que el contenedor no puede proteger contra).

Será subprocesos si la inmodificable vista de la seguridad publica, y la modificables original nunca nunca modificado (incluidos todos los objetos de forma recursiva contenida en la colección!) después de la publicación de la inmodificable vista.

Si desea mantener modificar el original, entonces usted puede crear una defensiva copia del gráfico de objetos de su colección y de devolver un inmodificable vista de que, o el uso de un inherentemente seguro para subprocesos lista para comenzar con, y devolver un inmodificable vista de que.

Usted no devolver un unmodifiableList(synchonizedList(lista)) si usted todavía tiene la intención para acceder a la lista sincronizado después;si el estado mutable es compartido entre varios subprocesos, entonces todos los hilos deben sincronizar en el mismo bloquea cuando tienen acceso a ese estado.

Un objeto inmutable es, por definición, los subprocesos (suponiendo que nadie conserva referencias a las colecciones originales), por lo que la sincronización es no es necesario.

Envolver el exterior ArrayList uso de las Colecciones.unmodifiableList() evita que el cliente cambiar su contenido (y por tanto hace de hilo seguro), pero el interior ArrayLists todavía son mutables.

Envolver el interior ArrayLists uso de las Colecciones.unmodifiableList() demasiado evita que el cliente cambiar su contenido (y por tanto, los hace thread safe), que es lo que necesita.

Háganos saber si esta solución provoca problemas (sobrecarga, uso de memoria, etc);otras soluciones pueden ser aplicables a su problema.:)

EDITAR:Por supuesto, si las listas son modificados que NO son seguros para subprocesos.Supuse que no hay más modificaciones se realizan.

No estoy seguro si he entendido lo que están tratando de hacer, pero yo diría que la respuesta en la mayoría de los casos es "No".

Si la instalación de un ArrayList de ArrayList y ambos, el interior y exterior de las listas nunca puede ser cambiado después de la creación (y durante la creación de un solo hilo se tiene acceso al interior y exterior de las listas), son probablemente los subprocesos, por un contenedor (si ambos, interior y exterior de las listas se envuelven de tal manera que la modificación de las que es imposible).Todas las operaciones de sólo lectura en ArrayLists son más probable es thread-safe.Sin embargo, el Sol no garantía ellos se thread-safe (también para las operaciones de sólo lectura), así que a pesar de que esto podría funcionar ahora, podría romper en el futuro (si el Sol crea algunos interna de almacenamiento en caché de datos para un acceso más rápido, por ejemplo).

Esto es necesario si:

  1. Todavía es una referencia a la original modificables en la lista.
  2. La lista posiblemente se accede a través de un iterador.

Si desea leer desde el ArrayList por el índice sólo se podría asumir que este es thread-safe.

En caso de duda, eligió el sincronizado de contenedor.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top