IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Collection et Stream Java Discussion :

Collection et multi Thread


Sujet :

Collection et Stream Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    382
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 382
    Par défaut Collection et multi Thread
    Bonjour, je suis en train de faire un serveur / client pour communiquer sur un réseau. Mais j'ai plusieurs problèmes et j'aimerai avoir votre avis. En gros j'ai :
    La classe Serveur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    public class Serveur
    {
         ArrayList<client> clients ;   
     
         public synchronized void sendAll(){}
     
         public synchronized void sendTo(){}
     
         public synchronized void AddClient(){}
     
         public synchronized void delClient(){}
     
         public synchronized final List<Client> getClient(){}
     
    }
    Ensuite j'ai ma classe client : ( Gestion des clients ).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public class Client {
         objetProtocole protocole ;
         String pseudo ;
     
         public String getPseudo(){}
         public void setPseudo(String pseudo){}
    }
    Classe protoles ( Faut-il en faire une pour chaque client ? utiliser un Singleton... pour le moment j'utilise un Singleton , ou ne serait-il pas mieux d'utiliser une classe interne dans serveur... )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    public class Protocole {
        public synchronized public void parseClientMessage(){}
         public synchronized public void parserServeurMessage(){}
    }
    // Cette classe me permet de parser les messages et de mettre en forme les autres messages.


    En gros que le serveur puisse :
    - Parser les messages des clients
    - Envoye un message à un client ou plusieur
    - Pouvoir retourner la liste des clients à un autre clients
    - J'aimerais que le serveur puissse faire un kick automatique donc dois-je mettre cette méthode dans protocole ou la classe serveur...

    Mais je suis perdu un peu pour le moment. donc si vous pouviez me donner un coup de main...

    Merci de votre aide

  2. #2
    Membre éclairé Avatar de orelero
    Étudiant
    Inscrit en
    Novembre 2004
    Messages
    389
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2004
    Messages : 389
    Par défaut
    salut

    Pour la gestion des clients, une bonne solution que j'ai adopté pour mon jeu multijoueurs c'est de les gérer selon des groupes. Ca permet d'envoyer les bonnes choses aux bonnes personnes et de facilement lister les clients :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    public class GroupStore implements Serializable
    {
    	static final long serialVersionUID = 3L;
     
    	private HashMap<String,LinkedList> groupStore;
     
    	public GroupStore()
    	{
    		groupStore = new HashMap<String,LinkedList>();
    	}
     
    	private void addGroup(String ref) //ref: nom du groupe
    	{
    		groupStore.put(ref,new LinkedList());
    	}
     
    	public void removeGroup(String ref)
    	{
    		groupStore.remove(ref);
    	}
     
    	public LinkedList getGroup(String ref)
    	{
    		return groupStore.get(ref);
    	}
     
    	public void addToGroup(Object o, String ref)
    	{
    		System.out.println("groupStore:"+groupStore);
    		LinkedList ll = groupStore.get(ref);
    		if(ll==null) addGroup(ref);
    		groupStore.get(ref).add(o);
    	}
     
    	public void removeFromGroup(Object o, String ref)
    	{
    		LinkedList ll = groupStore.get(ref);
    		if(ll!=null)ll.remove(o);
    	}
    }
    - J'aimerais que le serveur puissse faire un kick automatique donc dois-je mettre cette méthode dans protocole ou la classe serveur...
    ça semble plus logique d'avoir ça dans une classe "Commande".
    là c'est à toi de voir.

    Sinon quand tu mets le mot clé synchronized partout, je trouve ça bizarre. Moi j'en aurai pas mis dans les methode où il n'y a que lecture des données (une méthode synchronisée je crois que c'est la plus longue d'accés aprés une methode invoquée par reflexion !).
    Je trouve que le mieux c'est d'envoyer/recevoir les données selon une queue de messages(je suppose que tu utilises pas nio) (essaye de voir dans ça: ).
    Comme ça, tes differents thread clients alimentent la queue et le thread où tu gere tous les messages n'a plus qu'à lire un par un les messages.

    Voilà, j'ai essayé de t'aider avec le peu que je sais

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    382
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 382
    Par défaut
    En gros mon code ressemble a ceci :

    Un client :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    // Ecoute les message des clients :
    public void run()
    {
       String buffer ;
       while(  ( carLu = in.read() )  != -1 )
       {
          buffer+= carLu ;
          if( carLu = \n et carLuAvant = \r )
          {
             monObjetProtocol.parseClientMessage( buffer ) ;
             /* monObjetProtocol est identique pour chaque client */
          }
       }
    }
    La méthode parseClientMessage marche en gros comme ca :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    public synchronized void parseClientMessage(String message )
    {
       if( regexMessageperso == true )
       {
           sendTo( message, clientDestinataire );
       }
       else
       {
           sendAll( message ) ;
        }
    }
    D'ou l'utilisation de synchronized.


    Donc le mieux serait d'avoir une queue alimenté par les clients + lesMessageServeur
    Et de l'autre la classe Protocole qui li et vide la queue ?

  4. #4
    Membre éclairé Avatar de orelero
    Étudiant
    Inscrit en
    Novembre 2004
    Messages
    389
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2004
    Messages : 389
    Par défaut
    Si les données envoyées dépassent la vingtaine de bytes (je dis ça un peu au pif), vaudrait mieux utiliser readFully au lieu de lire caractère par caractère non (y'a un gain de vitesse) ? Si oui, il suffit de réservéer des bytes en tête de message pour la taille du message envoyé, comme ça à la reception il suffit de lire ces bytes pour connaitre la taille et de lire la suite avec un readfully.
    Pour ce qui est d'utiliser une queue, moi perso je trouve ça trés pratique, au moins la seule chose à synchroniser c'est cette queue et donc si tu utilises SynchronousQueue le travail est déjà fait.
    Dans mon cas j'utilise énormément les listes de l'api Javolution qui offre une vue synchronisée (FastList, etc...) et qui en plus sont recyclable (donc trés peu de créations d'objets).

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    382
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 382
    Par défaut
    Peut tu me montrer un exemple parce que je ne voie pas du tout comment je peux faire avec ta méthode...
    En effet je regarde et je test mais je suis obligé de synchronized mes méthodes...

  6. #6
    Membre éclairé Avatar de orelero
    Étudiant
    Inscrit en
    Novembre 2004
    Messages
    389
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2004
    Messages : 389
    Par défaut
    En fait faudrait que tu definisses une classe abstraite Message.
    Dans cette classe, tu déclares au moins une structure commune pour contenir n'importe quel type de message, par exemple un simple tableau de bytes mais aussi des méthodes communes comme send(Group group) ou getMessageByteArray()

    Ensuite, pour ta queue qui s'occupe d'empiler les messages à envoyer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     ConcurrentLinkedQueue<Message> messageOutQueue = new  ConcurrentLinkedQueue<E><Message>();
    *

    et celle qui empile les messages reçus:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     ConcurrentLinkedQueue<Message> messageInQueue = new  ConcurrentLinkedQueue<E><Message>();
    *

    Tu peux par exemple stocker ces 2 queues en statique dans une class MessageInOut.

    *ConcurrentLinkedQueue<E> permet de faire des opérations de lecture/écriture/suppression sans à y mettre d'accesseurs synchronisés ! Donc ça convient bien à ton cas je pense.

    Depuis le Thread client, à la reception, il faudra que tu recupères le message et le mette dans un tableau de bytes. Ensuite tu peux créer un objet qui dérive du type Message avec ce tableau et tu empiles cet objet dans messageOutQueue en faisant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MessageInOut.messageOutQueue.add(monObjetMessage);
    Le Thread qui s'occupe de lire les éléments empilés de messageOutQueue va récupéré l'élément le plus vieux de la queue en faisant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Message messageLu = MessageInOut.messageOutQueue.poll()
    et va appeler sa méthode send héritée de Message.

    Ce même Thread s'occupe aussi de lire les éléments empilés de messageInQueue.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [EJB3] ConcurrentModificationException collection list multi-thread jboss
    Par gudepier42 dans le forum Java EE
    Réponses: 1
    Dernier message: 10/05/2010, 13h09
  2. Tri multi-threadé
    Par Tifauv' dans le forum C
    Réponses: 8
    Dernier message: 28/06/2007, 09h00
  3. Réponses: 16
    Dernier message: 30/01/2004, 11h05
  4. [VB6][active x] faire du multi-thread avec vb
    Par pecheur dans le forum VB 6 et antérieur
    Réponses: 9
    Dernier message: 20/05/2003, 12h01
  5. [Kylix] exception qtinft.dll et multi-threading
    Par leclaudio25 dans le forum EDI
    Réponses: 3
    Dernier message: 27/03/2003, 18h09

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo