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

Design Patterns Discussion :

singleton et multithreading [Singleton]


Sujet :

Design Patterns

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    255
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 255
    Par défaut singleton et multithreading
    Le singleton est-il compatible avec le multithreading ?

    Le fait que l'instance du singleton soit partageable entre plusieurs thread fait que ses données peuvent être modifiées par plusieurs threads simultanément...

    En fait j'imagine que cette question ramène à toute classe qui met à disposition des données directement ou indirectement statiques (indirectement : ici une instance est accessible statiquement).

    Habituellement on doit protéger les données qui peuvent être modifiées par plusieurs threads.

    Doit-on alors prévoir pour tout singleton une protection similaire afin d'être "MultithreadSafe" ?

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    pour protéger ton singleton tu peut lui associer un attribut booléen :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    classe singleton {
      privé booleen verou;
    }
    Suivant la valeur de cet attribut tu permet l'accès au singleton ou non.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    methode get_instance(){
      ....
      SI(this.verou){
        insérer demande dans liste d'attente;
      }
      SINON{
        retourner objet
      }
    }
    
    methode set_verrou(valeur){
      this.verou = valeur;
    }
    Dernière modification par Invité ; 04/09/2009 à 20h24.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    255
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 255
    Par défaut
    ta reponse est donc oui ? pour la methode je prefererais utiliser les outils de synchronisation du langage !

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    255
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 255
    Par défaut
    Citation Envoyé par mehdiing Voir le message
    Bonjour,
    pour protéger ton singleton tu peut lui associer un attribut booléen :

    [...]
    Voici une implémentation en C# de cette idée ; ça ajoute juste une méthode de release de l'instance, ça pourrait peut-être aller.

    Le soucis principal c'est que si l'utilisateur du singleton fait simplement instanceRef=null ou même s'il n'appelle pas la méthode Release, le singleton reste verrouillé... il faut donc bien faire attention.

    J'aurai aimé quelque chose de plus systématique... mais cela semble impossible !

  5. #5
    ego
    ego est déconnecté
    Rédacteur

    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juillet 2004
    Messages
    1 883
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Architecte de système d'information
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 883
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par behess Voir le message
    Le singleton est-il compatible avec le multithreading ?

    Le fait que l'instance du singleton soit partageable entre plusieurs thread fait que ses données peuvent être modifiées par plusieurs threads simultanément...

    En fait j'imagine que cette question ramène à toute classe qui met à disposition des données directement ou indirectement statiques (indirectement : ici une instance est accessible statiquement).

    Habituellement on doit protéger les données qui peuvent être modifiées par plusieurs threads.

    Doit-on alors prévoir pour tout singleton une protection similaire afin d'être "MultithreadSafe" ?
    2 autres solutions "mieux"...je pense :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public Class MySingleton {
      private static MySingleton instance;
    
      static {
          instance = new MySingleton ();
      }
    
      public static MySingleton getInstance() { return instance; }
    }
    L'autre solution est d'utiliser Spring !

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    255
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 255
    Par défaut
    Oui c'est une solution classique pour un singleton.

    Mais ce que je recherche c'est à bloquer cet appel à getInstance() tant qu'un autre thread UTILISE cette même instance.

    C'est à dire tant qu'une référence à cette instance existe en dehors du Singleton.

    J'ai pensé aux références faibles mais je ne vois pas trop comment faire, ça à l'air ardu.

  7. #7
    Membre émérite
    Avatar de Antoine_935
    Profil pro
    Développeur web/mobile
    Inscrit en
    Juillet 2006
    Messages
    883
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur web/mobile

    Informations forums :
    Inscription : Juillet 2006
    Messages : 883
    Par défaut
    Citation Envoyé par ego Voir le message
    2 autres solutions "mieux"...je pense :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public Class MySingleton {
      private static MySingleton instance;
    
      static {
          instance = new MySingleton ();
      }
    
      public static MySingleton getInstance() { return instance; }
    }
    Ce qui est dommage avec cette solution, c'est qu'on perd le lazy instantiation.

    Personnellement, je préfère cette méthode:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class Singleton {
        private static Singleton instance = null;
    
        public static synchronized Singleton getInstance() {
            if(instance == null)
                instance = new Singleton();
            
            return instance;
        }
    }
    On pourrait me rétorquer qu'on perd des performances si deux élements veulent l'obtenir en même temps, mais... sincèrement, la perte n'est pas extraordinaire.

    Après, bien entendu, il est important de synchroniser les accès aux méthodes et attributs de ce singleton. Mais oui, le singleton peut être utilisé en multithread.
    Si tu tiens absolument à bloquer l'objet tant qu'il n'est pas relaché, tu peux rajouter une méthode getLock dessus, qui retournerait un ReentrantLock assigné à cette instance. Tu peux alors locker l'instance et la relacher quand tu n'en as plus besoin. Mais là tu risques de perdre du temps à l'exécution.
    Il vaut mieux synchroniser seulement ce qui en a besoin.

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    255
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 255
    Par défaut
    Oui en fait c'est stupide, autant synchroniser toutes les méthodes d'instance... c'est carrément plus simple ! Mdr.

    Que je suis con parfois.

  9. #9
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 699
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 699
    Par défaut
    Bonsoir
    Une autre solution pour éviter les pbs de synchro d'appel a get_instance peut être de créer le singleton avant le lancement des threads applicatives.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    255
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 255
    Par défaut
    ça aussi c'est pas con...

  11. #11
    Membre émérite
    Avatar de Antoine_935
    Profil pro
    Développeur web/mobile
    Inscrit en
    Juillet 2006
    Messages
    883
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur web/mobile

    Informations forums :
    Inscription : Juillet 2006
    Messages : 883
    Par défaut
    Citation Envoyé par Antoine_935 Voir le message
    Ce qui est dommage avec cette solution, c'est qu'on perd le lazy instantiation.
    Vous souvenez vous de cette réponse que j'ai posté plus haut ?
    Eh bien, après un des cours d'ajourd'hui, je réalise que je me suis planté, en partie du moins. La suite devrait être sufisamment explicite.

    Class: Main.java
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public class Main {
        public static void main(String[] args) {
            System.out.println("Entered main function");
            Loading.getInstance();
        }
    }
    Class: Loading.java
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class Loading {
        private static Loading instance;
    
        static {
            System.out.println("Now creating the instance");
            instance = new Loading();
        }
    
        public static Loading getInstance() {
            return instance;
        }
    }
    Resultat:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Entered main function
    Now creating the instance
    Cela est du au fait que Java fait lui-même de la lazy instantiation pour les classes. Loading ne sera pas chargé avant qu'on n'en ait besoin.

    Autrement dit, si la seule méthode statique de Loading est getInstance, alors on peut se servir du clinit, tout en conservant le côté lazy.

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

Discussions similaires

  1. Singleton et multithreading
    Par alladdin dans le forum Langage
    Réponses: 8
    Dernier message: 29/07/2010, 23h31
  2. Singleton et multithread
    Par totoche dans le forum Servlets/JSP
    Réponses: 2
    Dernier message: 25/05/2010, 18h05
  3. Singleton et Multithreading
    Par behess dans le forum C#
    Réponses: 22
    Dernier message: 09/09/2009, 11h09
  4. Singleton et multithreading
    Par Alp dans le forum C++
    Réponses: 17
    Dernier message: 06/08/2006, 02h49

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