2010-05-21 4 views
32

Le vecteur est synchronisé, ArrayList n'est pas synchronisé mais nous pouvons synchroniser un ArrayList par Collections.synchronizedList(aList), alors qui fonctionnera mieux et plus vite?Vecteur vs Collections.synchronizedList (ArrayList)

+1

S'il s'agit d'un C#, veuillez marquer votre question avec "C#" ou ".NET". – FrustratedWithFormsDesigner

+1

Pourquoi n'écrivez-vous pas un test et découvrez-le? – skaffman

+0

Pouvez-vous expliquer le modèle d'utilisation? 1) Beaucoup d'écritures/beaucoup de lectures 2) Peu d'écritures, beaucoup de lectures, 3) Beaucoup d'écritures, peu de lectures 4) peu/peu n'ont pas besoin d'optimisation – TJR

Répondre

4

Les collections synchronisées sont une perte de temps et dangereuses. Un exemple trivial pourquoi ils sont mauvais est de considérer deux fils en cours d'exécution d'une boucle en même temps sur la même collection:

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

Notre liste peut être synchronisé (par exemple un vecteur) et ce code serait encore casser horriblement. Pourquoi? Parce que les appels individuels à size(), get(), remove(), sont synchronisés, mais un thread peut toujours supprimer des éléments de la liste pendant que l'autre itère sur lui. En d'autres termes, nous avons une condition de concurrence et l'utilisation de collections synchronisées ne nous a rien apporté.

Pour réparer la course, nous devons synchroniser l'ensemble de l'opération sur la collection ou utiliser Java 5 pour faire de même. Ce bloc de code est maintenant thread-safe car un seul thread peut exécuter la boucle à la fois. Et maintenant, il n'y a aucune raison d'utiliser une collection synchronisée. Nous pouvons utiliser un ArrayList au lieu d'un vecteur et nous sauver la peine de performance sur tous ces appels synchronisés. Par conséquent, n'utilisez pas de collections synchronisées. Si vous avez plusieurs threads qui frappent la même liste, vous devez protéger les opérations de la liste, pas les appels individuels.

+9

"Les collections synchronisées sont une perte de temps." -- trop général. Les collections synchronisées ont un but. Vous donnez juste un exemple de la façon de les utiliser mal. Argument de l'homme de paille. – thejoshwolfe

+0

Ils sont une perte de temps tout à fait littéralement. Le mot-clé synchronized impose une pénalité d'appel même si la collection est utilisée exclusivement par un seul thread. Et la plupart des collections seraient utilisées exclusivement par un seul fil. Et même si elles sont partagées, la synchronisation d'un appel individuel permet toujours des conditions de course de sorte qu'elles ne sont pas adaptées à l'usage auquel elles sont destinées. Le développeur gaspille juste leur temps à trouver des bogues dans leurs collections soi-disant thread-safe. Autrement dit, ces collections sont toxiques et ne devraient jamais être utilisées sauf lorsqu'il n'y a pas moyen de les éviter (par exemple, cas hérités, J2ME, etc.). – locka

+1

La synchronisation était lente dans Java 1.3 et antérieur. En Java moderne, c'est mieux. http://www.ibm.com/developerworks/java/library/j-jtp04223/index.html Aussi, encore une fois avec des arguments spécieux paille. Personne n'utilise la synchronisation avec une situation connue pour être monothread. Votre premier exemple est simplement une mauvaise programmation et aucune collection ne peut jamais compenser cela. Vous devez simplement penser à ce qui est atomique ou non, quelle que soit la collection que vous utilisez. Jetez un oeil au code remove() dans ArrayList et vous verrez pourquoi cette méthode doit être synchronisée pour maintenir l'intégrité de la liste. – Gus