Partage
  • Partager sur Facebook
  • Partager sur Twitter

Vector de ConcurrentHashMap (efficacité de mise à jour)

    12 juillet 2011 à 19:05:48

    Bonsoir !
    J'ai un tableau Vector (j'ai choisi vector parce que ces méthodes sont synchronisées ce qui me facilite la tâche vu que mon application est multi-thread) qui contient un nombre indéterminé de ConcurrentHashMap qui, ces-dernières contiennent différent objets comme des strings ou des PrintWriter. (ouf :p)
    public Vector<ConcurrentHashMap<?, ?>> clients = new Vector<ConcurrentHashMap<?, ?>>();
    

    Depuis chaque thread lancé, je souhaite mettre à jour une valeur du ConcurrentHashMap à l'indice du numéro de client du tableau Vector 'clients', je n'ai pas trouvé moi-même d'autre méthode que de procéder comme ceci :
    infoClient.replace("SALLE", salle);
    _Serveur.clients.set(_NumeroClient, infoClient);
    

    Mais de cette manière je supprime entièrement le ConcurrentHashMap déjà présent dans le vector et le remplace par le nouveau avec la nouvelle valeur, c'est ce qui me pose problème, je pense que c'est une grosse perte d'efficacité.
    J'aurai voulu savoir si :
    - c'est le cas.
    - si il est possible de faire pareil avec des méthodes de Vector ou ConcurrentHashMap
    - sinon vous me conseilleriez quoi d'autres d'équivalent pour obtenir le même effet mais en plus efficace ?
    Merci d'avance.
    • Partager sur Facebook
    • Partager sur Twitter
      14 juillet 2011 à 18:37:30

      Plop,

      Le fait d'utiliser Vector car il est synchronisé est inutile selon moi. La ConcurrentHashMap est thread-safe et apporte un niveau de concurrence plus élevé que les méthodes "synchronized" (et plus performantes).
      Ensuite, j'utiliserai plutôt une Map qu'un Vector, le fait de se baser sur indice pour récupérer ta map est, selon moi, dangereux alors que la map t'assure d'avoir une clé unique.

      En fait dans ton cas, il serait plus simple de créer un objet encapsulant une ConcurrentMap où tu y places des méthodes put/get, ... et tu crées une Map de Key/Cet objet. Car effectivement créer et supprimer des map juste pour insérer ou remove un élément n'est pas... génial :)
      • Partager sur Facebook
      • Partager sur Twitter
        14 juillet 2011 à 22:54:36

        D'accord mais l'avantage que j'avais à utilisé le Vector c'est qu'a chaque .removeElementAt() il recréait un tableau en réattribuant des numéros ordonnés à chaque entrée, ce qui est un avantage lorsqu'on le parcours pour récupérer tous les sockets de tous les clients pour leur envoyé un message.
        • Partager sur Facebook
        • Partager sur Twitter
          15 juillet 2011 à 9:32:33

          Plop,

          Ce que je veux dire c'est que se baser sur l'indice d'une Collection pour récupérer un objet est, selon moi, dangereux. Dans ce cas, autant directement utilisé une Map. Si tu supprimes un élément dedans, cela n'impacte en rien le reste de ta collection, ce qui n'est pas le cas du Vector. De plus, le fait que ta Collection soit synchronisé ne te sauve "sauve" en rien. Imagine l'exemple suivant :

          3 threads qui effectue les tâches suivantes :
          • - Renvoie le premier élément
          • - Supprime le premier élément
          • - Renvoie le deuxième élément


          Qu'est ce qui t'assure que le thread 2 ne passera pas avant le premier et donc le premier renverrait le deuxième élément et le troisième le troisième élément ? Et pourtant tout est bien synchronisé. Pour débugger un problème comme cela, il te faudrait un minimum de temps puisqu'il ne se reproduirait qu'occassionnellement. C'est pour cela que je te conseille fortement d'utiliser une Map.
          • Partager sur Facebook
          • Partager sur Twitter
            15 juillet 2011 à 9:54:16

            Je pense que tu devrais plutôt opter pour une ConcurrentHashMap contenant des HashMap normales.

            Je m'explique :
            D'abord la Map à la place du Vector pour le problème des index/identifiants. -Trouver des identifiants uniques n'est pas un problème.

            Ensuite la Map normale et non pas la concurrente poures les propriétés de chaque client parce qu'à moins que plusieurs threads modifient les propriétés du même client en même temps, ce n'est pas utile. En revanche la ConcurrentHashMap au lieu d'une Map normale même synchronisée pour la liste des clients, ça sera beaucoup plus sûr et plus rapide car plusieurs threads différents modifient effectivement la liste globale des clients.

            Tu aurais avantage à définir ta propre classe encapsulant les propriétés de tes clients et en synchronisant seulement les accesseurs qui le nécéssitent vraiment. Ce serait probablement plus rapide.
            • Partager sur Facebook
            • Partager sur Twitter
              15 juillet 2011 à 12:10:43

              Donc si j'ai bien compris :
              - A la place du Vector j'utilise une ConcurrentHashMap qui contiendras toutes les clients sous formes de HashMap normales.
              - Je dois créer une classe qui va initialisé les informations de chaque clients et qui va contenir les méthodes qui vont changé son contenu.
              Mais si je créer un objet par client, je n'ai pas besoin de le placer dans une HashMap, mais directement rajouté l'objet dans une ConcurrentHashmap non ?
              • Partager sur Facebook
              • Partager sur Twitter
                15 juillet 2011 à 13:02:32

                Citation

                Mais si je créer un objet par client, je n'ai pas besoin de le placer dans une HashMap, mais directement rajouté l'objet dans une ConcurrentHashmap non ?   


                Oui, exactement. Au final le mieux que tu puisses avoir c'est une ConcurrentHashMap<Integer,ClientInfo> et dans ClientInfo tu ne synchronises que les setters qui en ont vraiment besoin (les getters n'ont pas besoin d'être synchronisés normalement).

                Maintenant si tu préfères garder une HashMap plutôt que d'encapsuler dans une classe ClientInfo, tu peux aussi, mais à mon sens c'est moins bien. Au fait si tu as besoin de la flexibilité des HashMap, rien ne t'interdit de l'étendre.
                • Partager sur Facebook
                • Partager sur Twitter
                  15 juillet 2011 à 14:39:51

                  Je pense que je vais opté pour ta solution si d'après toi elle est plus efficace !
                  Merci beaucoup pour votre aide :)
                  • Partager sur Facebook
                  • Partager sur Twitter

                  Vector de ConcurrentHashMap (efficacité de mise à jour)

                  × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                  × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                  • Editeur
                  • Markdown