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

avec Java Discussion :

[Singleton] Toutes les méthodes doivent-elles être 'synchronized'


Sujet :

avec Java

  1. #1
    Membre habitué
    Inscrit en
    Décembre 2005
    Messages
    251
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 251
    Points : 143
    Points
    143
    Par défaut [Singleton] Toutes les méthodes doivent-elles être 'synchronized'
    Bonjour à tous,

    J'utilise une socket pour envoyer des données.

    Il y a plusieurs thread qui y ont accès. Notamment un thread qui envoie des trames de "présence" et un autre des trames de "commande". La ressource socket est donc partagée mais il ne peut en avoir qu'une instance.

    Du coup la classe SocketCom est en singleton.
    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 SocketCom
    {
            private java.net.DatagramSocket socket = null;
            private InetAddress addr;
            private int port = 6680;
            private int receiveDelay = 100;
            private static SocketCom instance = null;
     
            public static synchronized SocketCom getInstance() throws IOException
            {
                if(instance==null)
                {
                    instance = new SocketCom();
                    instance.open();
                }
                return instance;
            }
     
            private void socketCom() {    ........}
     
            private void open() throws IOException {.....}
     
            public synchronized void sendKeepAlive() throws IOException {
     
               DatagramPacket dp = new DatagramPacket(KeepAlive, 2, addr, port);
               socket.send(dp);
            }
     
            public synchronized void commande1() throws IOException {
     
               DatagramPacket dp = new DatagramPacket(commande1, 2, addr, port);
               socket.send(dp);
            }
     
            public synchronized void commande2() throws IOException {
     
               DatagramPacket dp = new DatagramPacket(commande2, 2, addr, port);
               socket.send(dp);
            }
    }
    Quelqu'un saurait-il me dire si toutes les méthodes doivent déclarées synchronized ?

    Merci d'avance pour votre aide.

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut,

    Toutes les méthodes qui manipulent la même chose qui pour laquelle une manipulation par plusieurs méthodes par plusieurs threads pourraient causer des conflits.

    Par exemple, dans le cas suivant, getNam() n'a pas besoin d'être synchronisé : on peut l'appeler sans conflit avec les 3 autres méthodes :

    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
    public class Exemple {
     
        private final String name;
        private final List<IExempleListener> listeners;
     
        public Exemple(Striing name) {
            this.name=name;
            this.listeners=new ArrayList<>();
        }
     
        public String getName() {
             return name;
        }
     
        public synchronized void add(IExempleListener listener) {
             if ( !listeners.contains(listener) ) {
                listeners.add(listener);
            }
        }
     
        public synchronized void remove(IExempleListener listener) {
             listeners.remove(listener);
        }
     
        protected synchronized void fireEvent(IExempleEvent event) {
            for(IExempleListener listener : listeners) {
                 listener.handle(event);
            }
        }
     
    }
    Si on avait 2 listes dont les modifications n'étaient pas en conflits entre elles, comme une autre liste pour un autre type de listener, on pourrait synchroniser chacune des listes, en faisant un bloc synchronisé sur l'instance de liste elle-même :

    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
    41
    42
    43
    public void add(IExempleListener listener) {
        synchronized ( listeners ) {
                if ( !listeners.contains(listener) ) {
                  listeners.add(listener);
               }
        }
    }
     
    public void remove(IExempleListener listener) {
        synchronized ( listeners ) {
             listeners.remove(listener);
        }
    }
     
    protected void fireEvent(IExempleEvent event) {
        synchronized ( listeners ) {
            for(IExempleListener listener : listeners) {
                 listener.handle(event);
            }
        }
    }
     
    public void add(IAutreExempleListener listener) {
        synchronized ( autrelisteners ) {
                if ( !autrelisteners .contains(listener) ) {
                  autrelisteners .add(listener);
               }
        }
    }
     
    public void remove(IAutreExempleListener listener) {
        synchronized ( autrelisteners  ) {
             autrelisteners.remove(listener);
        }
    }
     
    protected void fireEvent(IAutreExempleEvent event) {
        synchronized ( autrelisteners  ) {
            for(IAutreExempleListener listener : autrelisteners ) {
                 listener.handle(event);
            }
        }
    }
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Membre habitué
    Inscrit en
    Décembre 2005
    Messages
    251
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 251
    Points : 143
    Points
    143
    Par défaut
    Merci de ta réponse,

    Donc dans mon cas la seule ressource partagée est socket dans les méthodes "commande". Donc pas de besoin de synchroniser si je comprends bien.

    Est ce que c'est bien ça ?

    Merci

  4. #4
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Si bien sûr, c'est la même instance de socket qui est utilisée pour plusieurs commandes. Si 2 threads cherchent à appeller commande1() et commande2() en même temps, ça ne va pas fonctionner (au mieux tu aurais les messages qui se mélangent). Toutes les méthodes qui font socket.send() doivent être synchronisées entre elles. Par contre, la génération du Singleton peut être synchronisées à part : ce qu'on cherche à faire, c'est simplement d'éviter d'avoir 2 singletons. Enfin, là c'est théorique bien sûr, puisque si le Singleton n'existe pas, la socket non plus. Mais on pourrait imaginer qu'au lieu d'un singleton, on ait un pool, avec plusieurs instances de SocketCom : un pool avec un nombre d'instances initialisées et un maximum. Quand on demande au pool une instance, on bloque les autres demandes, tant qu'on a pas déterminé s'il y avait une instance libre, ou s'il fallait en créer une nouvelle (tant qu'on a pas atteint le max). Mais pendant qu'on bloque ce traitement, on peut ne pas bloquer les appels de commandes sur les instances de SocketCom qui sont sorties du pool, puisqu'elles ont chacune leur propre instance de Socket.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

Discussions similaires

  1. Les failles de sécurité doivent-elles être rendues publiques ?
    Par Hinault Romaric dans le forum Actualités
    Réponses: 56
    Dernier message: 03/02/2015, 00h39
  2. Les classes doivent-elles forcément être liées ?
    Par Ikki_2504 dans le forum Diagrammes de Classes
    Réponses: 6
    Dernier message: 26/12/2010, 23h44
  3. Les resources doivent-elles être placées dans Thèmes ?
    Par scapefrom dans le forum Windows Presentation Foundation
    Réponses: 1
    Dernier message: 03/08/2010, 15h58
  4. [EJB2.1 Entity] [BMP] les requetes doivent-elles se trouver directement dans les méthodes ?
    Par webspeak dans le forum Java EE
    Réponses: 2
    Dernier message: 24/03/2005, 08h34
  5. [Interface] Appeller toutes les méthodes héritées d'un class
    Par thibaut.d dans le forum Général Java
    Réponses: 4
    Dernier message: 25/01/2005, 08h42

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