2010-05-21 19 views
32

El vector está sincronizado, ArrayList no está sincronizado, pero podemos sincronizar un ArrayList por Collections.synchronizedList(aList), por lo que funcionará mejor y más rápido?Vector vs Collections.synchronizedList (ArrayList)

+1

Si esto es C#, por favor marque su pregunta con "C#" o ".NET". – FrustratedWithFormsDesigner

+1

¿Por qué no escribes una prueba y la descubres? – skaffman

+0

¿Puedes explicar el patrón de uso? 1) Muchas escrituras/muchas lecturas 2) Pocas escrituras, muchas lecturas, 3) Muchas escrituras, pocas lecturas 4) pocas/pocas no necesita optimización – TJR

Respuesta

4

Las colecciones sincronizadas son una pérdida de tiempo y peligroso. Un ejemplo trivial por qué son malas es considerar dos hilos de ejecución de un bucle al mismo tiempo en la misma colección:

int i = 0; 
while (i < list.size()) 
{ 
    if (testSomeCondition(list.get())) { 
    list.remove(i); 
    else 
    i++; 
} 

Nuestra lista podría ser sincronizado (por ejemplo, un vector) y el código todavía romper horriblemente. ¿Por qué? Debido a que las llamadas individuales a size(), get(), remove(), están sincronizadas, pero un subproceso aún podría estar eliminando elementos de la lista mientras el otro itera sobre él. En otras palabras, tenemos una condición de carrera y el uso de colecciones sincronizadas no nos ha ganado nada.

Para arreglar la carrera, tenemos que sincronizar toda la operación en la colección o usar bloqueos de simultaneidad Java 5 para hacer lo mismo.

synchronized (list) { 
    int i = 0; 
    while (i < list.size()) 
    { 
    if (testSomeCondition(list.get())) { 
     list.remove(i); 
    else 
     i++; 
    } 
} 

Este bloque de código ahora es seguro para subprocesos, ya que solo un subproceso puede ejecutar el bucle a la vez. Y ahora no hay ninguna razón para usar una colección sincronizada. Podemos usar una ArrayList en lugar de un Vector y ahorrarnos la penalización de rendimiento en todas esas llamadas sincronizadas.

No utilice colecciones sincronizadas. Si encuentra que tiene varios hilos que llegan a la misma lista, debe proteger las operaciones de la lista, no las llamadas individuales.

+9

"Las colecciones sincronizadas son una pérdida de tiempo". -- demasiado general. Las colecciones sincronizadas tienen un propósito. Solo estás dando un ejemplo de cómo usarlos mal. Argumento del hombre paja – thejoshwolfe

+0

SON una pérdida de tiempo bastante literalmente. La palabra clave sincronizada impone una penalización de llamada incluso si la colección es utilizada exclusivamente por un único hilo. Y la mayoría de las colecciones serían utilizadas exclusivamente por un solo hilo. E incluso si se comparten, sincronizar una llamada individual aún permite las condiciones de carrera, por lo que no son aptos para el propósito. El desarrollador simplemente pierde SU tiempo encontrando errores en sus colecciones supuestamente seguras para hilos. En pocas palabras, estas colecciones son tóxicas y nunca deben usarse, excepto cuando no hay forma de evitarlas (por ejemplo, casos heredados, J2ME, etc.). – locka

+1

La sincronización fue lenta en Java 1.3 y versiones anteriores. En java moderno, es mejor. http://www.ibm.com/developerworks/java/library/j-jtp04223/index.html También, de nuevo con argumentos engañosos. Nadie utiliza la sincronización con una situación que se sabe que es de un solo subproceso. Su primer ejemplo es simplemente mala programación y ninguna colección puede compensar eso. Simplemente debe pensar en lo que es o no es atómico, independientemente de la colección que use. Eche un vistazo al código remove() en ArrayList y verá por qué este método debe sincronizarse para mantener la integridad de la lista. – Gus