¿Debo usar una colección de vectores sincronizados anterior, ArrayList con acceso sincronizado o Collections.synchronizedList o alguna otra solución para el acceso concurrente?La mejor forma de controlar el acceso simultáneo a las colecciones de Java
No veo mi pregunta en Preguntas relacionadas ni en mi búsqueda (Make your collections thread-safe? no es lo mismo).
Recientemente, tuve que realizar pruebas de unidad de tipo en partes de la GUI de nuestra aplicación (básicamente usando API para crear marcos, agregar objetos, etc.). Debido a que estas operaciones son llamadas mucho más rápido que por un usuario, muestra una serie de problemas con los métodos que intentan acceder a los recursos que aún no se han creado o que ya no se eliminaron.
Un problema particular, sucediendo en el EDT, vino de recorrer una lista vinculada de vistas mientras la alteraba en otro hilo (obteniendo una ConcurrentModificationException entre otros problemas). No me preguntes por qué era una lista vinculada en lugar de una simple lista de arreglos (incluso menos que en general tenemos 0 o 1 vista dentro ...), así que tomé la ArrayList más común en mi pregunta (ya que un primo mayor).
De todos modos, no muy familiarizado con problemas de concurrencia, busqué un poco de información, y me pregunté qué elegir entre el Vector viejo (y probablemente obsoleto) (que tiene operaciones sincronizadas por diseño), ArrayList con un synchronized (myList) { }
alrededor de crítico secciones (operaciones de agregar/eliminar/caminar) o usar una lista devuelta por Collections.synchronizedList (ni siquiera está seguro de cómo usar esta última).
Finalmente elegí la segunda opción, porque otro error de diseño fue exponer el objeto (método getViewList() ...) en lugar de proporcionar mecanismos para usarlo.
Pero, ¿cuáles son los pros y los contras de los otros enfoques?
[EDITAR] Muchos buenos consejos aquí, difíciles de seleccionar. Elegiré los más detallados y proporcionaré enlaces/alimentos para pensamientos ... :-) También me gusta el de Darron.
En resumen:
- Como sospechaba, Vector (y su gemelo malvado, Hashtable así, probablemente) es en gran medida obsoleta, he visto a la gente diciendo su antiguo diseño no es tan bueno como las nuevas colecciones ', más allá de la lentitud de la sincronización obligada incluso en el entorno de subproceso único. Si lo mantenemos, es principalmente porque las bibliotecas antiguas (y partes de la API de Java) aún lo usan.
- A diferencia de lo que pensaba, Collections.synchronizedXxxx no son más modernos que Vector (parecen ser contemporáneos a Collections, es decir, Java 1.2!) Y en realidad no son mejores. Bueno saber. En resumen, debería evitarlos también.
- La sincronización manual parece ser una buena solución después de todo. Puede haber problemas de rendimiento, pero en mi caso no es crítico: operaciones realizadas en acciones del usuario, colección pequeña, sin uso frecuente.
- El paquete java.util.concurrent vale la pena tenerlo en cuenta, en particular los métodos CopyOnWrite.
espero que lo hizo bien ... :-)
También vea http://stackoverflow.com/questions/510632/whats-the-difference-between-concurrenthashmap-and-collections-synchronizedmapm – eljenso