Histoires de synchronisation...

Histoires de synchronisation... - Java - Programmation

Marsh Posté le 18-10-2002 à 11:52:32    

Je suis en train de lire un truc dans la Javadoc qui m'intrigue un peu. Pour synchronizer un HashSet (par exemple), ils disent de faire le code suivant :

Code :
  1. Set s = Collections.synchronizedSet(new HashSet());
  2.       ...
  3.   synchronized(s) {
  4.       Iterator i = s.iterator(); // Must be in the synchronized block
  5.       while (i.hasNext())
  6.           foo(i.next());
  7.   }


 
Ce que je comprend pas, c'est l'utilité de la manière dont ont récupère le "synchronizedSet". Puisqu'on doit quand même gérer la synchronization. Logiquement, même si j'avais pas fait "synchronizedSet", mais un new simple de ma HashSet, si je met les instructions à risque dans des bloques "synchronized", mon truc sera tread-safe qd même, non ?

Reply

Marsh Posté le 18-10-2002 à 11:52:32   

Reply

Marsh Posté le 18-10-2002 à 11:56:53    

et ça :

Returns a synchronized (thread-safe) set backed by the specified set. In order to guarantee serial access, it is critical that all access to the backing set is accomplished through the returned set.


 
Selon vous, ça veut dire qu'on peut pas caster le Set obtenu en HashSet ?


Message édité par El_gringo le 18-10-2002 à 11:57:15
Reply

Marsh Posté le 18-10-2002 à 13:38:46    

Je pense que le synchronizedSet peut être accéder directement sans utiliser de bloc 'synchronized' (c'est à dire, lire un élément, ajouter un élément,...), sinon, ça n'a aucune utilité d'utiliser un Set synchronizé par rapport à un Set standard. En revanche, quand tu utilises un Iterator, pour être sûr que le set sous jacent n'est pas modifié entre le moment où tu instancies l'Iterator et le moment où tu finis de le parcourir, il faut utiliser un bloc synchronized.  
Et je ne pense pas que tu puisses caster le set obtenu par Collections.synchronizedSet() en HashSet mais seulement en Set (mais je pense que les méthodes disponibles sont les mêmes).

Reply

Marsh Posté le 18-10-2002 à 14:03:15    

Pour l'histoire du cast, je posais la question parce que je m'apprête à crééer un classe étendant HashSet qui, elle, aurait des méthode autres que celles de Set.


Message édité par El_gringo le 18-10-2002 à 14:03:53
Reply

Marsh Posté le 18-10-2002 à 14:07:24    

Et, apparement, si j'étend Vector plutot que HashSet, j'ai pas à me soucier de la synchronisation, même si j'utilise une énumération rendue par

Code :
  1. public Enumeration elements()

?

Reply

Marsh Posté le 18-10-2002 à 14:07:46    

El_Gringo a écrit a écrit :

Je suis en train de lire un truc dans la Javadoc qui m'intrigue un peu. Pour synchronizer un HashSet (par exemple), ils disent de faire le code suivant :

Code :
  1. Set s = Collections.synchronizedSet(new HashSet());
  2.       ...
  3.   synchronized(s) {
  4.       Iterator i = s.iterator(); // Must be in the synchronized block
  5.       while (i.hasNext())
  6.           foo(i.next());
  7.   }


 
Ce que je comprend pas, c'est l'utilité de la manière dont ont récupère le "synchronizedSet". Puisqu'on doit quand même gérer la synchronization. Logiquement, même si j'avais pas fait "synchronizedSet", mais un new simple de ma HashSet, si je met les instructions à risque dans des bloques "synchronized", mon truc sera tread-safe qd même, non ?




 
AMHA il y a deux choses :  
 
Les SynchronizedSets assurent que seul un thread a la fois manipule le contenu de ton Set : on te garantit l'atomicite des manipulations sur ton set. En d'autres termes tu as un acces atomique sequentiel au contenu du set.
 
La synchronisation d'objet assure que seul un thread a la fois manipule ton Set : Si tu desire creer un iterateur sur le contenu de ton set l'atomicite du synchronizedSet n'est pas suffisante. Non seulement tu ne veux pas que des objets soient ajoutes ou enleves de ton set en meme temps que tu fais une manipulation, mais en plus tu ne veux pas que ce soit le cas sur un ensemble de manipulations.  
 

Reply

Marsh Posté le 18-10-2002 à 14:15:54    

El_Gringo a écrit a écrit :

Et, apparement, si j'étend Vector plutot que HashSet, j'ai pas à me soucier de la synchronisation, même si j'utilise une énumération rendue par

Code :
  1. public Enumeration elements()

?




 
Bref, cette énumération récupérée permet d'énumérer une copie du contenu des éléments de ce vector ou d'énumérer les éléments eux même. J'm'explique : par exemple si je fais ça:
1 - je récupère une enumération à un instance donné.
2 - je vide mon Vector de tout ce qu'il contient
3 - j'utilise l'énumération récupérée en "1" pour énumérer les éléments. J'énumére les éléments qui étaient ds le Vector en "1" ou j'énumère rien du tout ?

Reply

Marsh Posté le 18-10-2002 à 15:37:57    

Faudrait verifier, mais je pense que elements() crée une copie des elements du Vector. Donc d'apres moi, l'énumération est inchangée après suppression du contenu du Vector. Mais je ne suis sur de rien, hein.


---------------
Au royaume des sourds, les borgnes sont sourds.
Reply

Marsh Posté le 18-10-2002 à 15:54:09    

R3g a écrit a écrit :

Faudrait verifier, mais je pense que elements() crée une copie des elements du Vector. Donc d'apres moi, l'énumération est inchangée après suppression du contenu du Vector. Mais je ne suis sur de rien, hein.




 
à priori je suis d'accord avec toi...

Reply

Marsh Posté le 18-10-2002 à 17:34:26    

à priori...

Reply

Marsh Posté le 18-10-2002 à 17:34:26   

Reply

Marsh Posté le 19-10-2002 à 11:31:22    

R3g a écrit a écrit :

Faudrait verifier, mais je pense que elements() crée une copie des elements du Vector. Donc d'apres moi, l'énumération est inchangée après suppression du contenu du Vector. Mais je ne suis sur de rien, hein.




je suis sur que ce n'est pas le cas pour iterator() de ArrayList mais pour elements de Vector je sais pas...
mais ca me parrait un peu lourd qu'il fasse une copie ...

Reply

Marsh Posté le 19-10-2002 à 12:32:48    

Il n'y a pas de copie pour elements(). J'ai fait quelques tests pour en être sûr, mais comme l'a dit benou ça serait pas efficace de copier tout le Vector avant d'itérer dessus.


---------------
"Colère et intolérance sont les ennemis d'une bonne compréhension." Gandhi
Reply

Marsh Posté le 21-10-2002 à 09:30:22    

benou a écrit a écrit :

 
je suis sur que ce n'est pas le cas pour iterator() de ArrayList mais pour elements de Vector je sais pas...
mais ca me parrait un peu lourd qu'il fasse une copie ...




 
Pour Iterator, ça parait logique ce que tu dis : la méthode remove perdrait vachement de son interêt si on bossait sur une copie des éléments.
Mais alors si j'utilise une enumération ds un contexte multi threads, 'faut que je synchronize mon vector autour de l'énumération, non ?

Reply

Marsh Posté le 21-10-2002 à 09:31:31    

genre :

Code :
  1. synchronize (monVector) {
  2. Enumeration enum = monVector.elements();
  3. //mon énumeration...
  4. }


 
non ?


Message édité par El_gringo le 21-10-2002 à 10:46:15
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed