2009-11-01 6 views
4

Je me demande si ce code va faire problème:java Sécurité du vecteur et du fil

J'ai un vecteur qui est partagé entre plusieurs threads. Chaque fois qu'un thread doit ajouter/enlever des trucs du vecteur je le fais sous un bloc synchronized. Cependant, le thread principal a un appel:

System.out.println("the vector's size: "+ vec.size()); 

qui n'est pas synchronized.

Cela devrait-il causer des problèmes?

+2

En aparté, vous devriez favoriser l'utilisation de l'API JDK 1.2 Collections (ArrayList ou LinkedList) conjointement avec Collections.synchronizedList (Liste) pour les synchroniser. Le vecteur est obsolète (avec Hashtable). – Adamski

+0

@Adamski Merci pour votre commentaire, qui m'a beaucoup aidé (bien que 3 ans)! ;) – brimborium

Répondre

7

Je suppose que vous faites référence à java.util.Vector.

En fait Vector.size()est synchronisée et renvoie une valeur conforme à l'état du vecteur (lorsque le thread appelant size() entre le moniteur.) Si elle retourne 42, puis à un moment donné dans le temps le vecteur contenait exactement 42 éléments.

Si vous ajoutez des éléments dans une boucle dans un autre thread, vous ne pouvez pas prédire la taille exacte, mais cela devrait fonctionner correctement à des fins de surveillance.

+3

+1 pour "à un moment donné". Peut ne pas être exactement conforme au code entourant la déclaration. Pour cela, vous devez ajouter votre propre synchronisation. – Thilo

12

Toutes les méthodes Vector sont synchronisées elles-mêmes, aussi longtemps que vous synchronisez uniquement autour d'une seule méthode, votre propre synchronisation n'est pas nécessaire. Si vous avez plusieurs appels de méthode, qui dépendent l'un de l'autre, par ex. quelque chose comme vec.get(vec.size()-2) pour obtenir le second dernier élément, vous devez utiliser votre propre synchronisation, sinon le vecteur peut changer entre vec.size() et vec.get().

0

Chacune des méthodes de java.util.Vector est synchronized, donc cela ne causera pas de problèmes pour quelque chose qui ne fait que noter la taille. Pour améliorer les performances, il est préférable de remplacer votre Vector par un ArrayList. Les méthodes de ArrayList ne sont pas synchronized, vous devrez donc synchroniser tous les accès vous-même.

+3

Quelles améliorations de performances attendez-vous si vous remplacez la classe Vector syncrhonisée par une ArrayList non synchronisée et ajoutez votre propre synchronisation autour de tous les appels de méthode sur ArrayList? – jarnbjo

+0

Dans de nombreux cas, la synchronisation mono-méthode est insuffisante, vous devez donc effectuer votre propre synchronisation. En utilisant Vector, vous finirez par synchroniser deux fois. –

+2

Quelle est l'incidence sur les performances de la synchronisation "double" si vous implémentez quelque chose comme 'synchronized (vec) {vec.get (vec.size() - 2);}'? – jarnbjo

0

l'esprit que vous pouvez toujours obtenir une version synchronisée d'une collection en utilisant Collections.synchronizedCollection(Collection<T> c) méthode statique ..

+0

Dans ce cas, la collection est une liste, donc Collections.synchronizedList (Liste c) serait mieux. – finnw