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

Langage Java Discussion :

Singleton et multithreading


Sujet :

Langage Java

  1. #1
    Membre averti
    Inscrit en
    Décembre 2005
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 19
    Par défaut Singleton et multithreading
    Bonjour,

    Je pense que j'ai un problème concernant l'implémentation du singleton. Pour le mettre clairement en évidence j'ai fait un petit code tout simple.

    Voici la classe qui doit être un 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
    41
     
     
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
     
     
    public class Toto {
     
    	private static Toto MONTOTO = null;
    	private List<String> maliste;
     
     
     
    	public Toto() {
    		super();
    		maliste = new ArrayList<String>();
    	}
     
    	public synchronized static Toto getSingleton(){
    		if(MONTOTO == null){
    			MONTOTO = new Toto();
    		}
    		return MONTOTO;
    	}
     
    	public void populateList(){
    		maliste.add("avion");
    		maliste.add("bateau");
    		maliste.add("voiture");
    		maliste.add("train");
    		System.out.println("pause");
    	}
     
    	public void readList(){
    		for (Iterator<String> iterator = maliste.iterator(); iterator.hasNext();) {
    			String current = (String) iterator.next();
    			System.out.println("  -----  " + current + "  ----- ");
    		}
    	}
    }
    Voici la classe qui l'utilise :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
     
    public class Tata {
     
    	public static void populateData(){
    		Toto.getSingleton().populateList();
    	} 
     
    	public static void readData(){
    		Toto.getSingleton().readList();
    	}
    }
    et enfin voici la classe de test :

    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
     
     
    import junit.framework.TestCase;
     
     
    public class Test extends TestCase{
     
     
    	public final void testPopulateData() {
    		Tata.populateData();
    	}
     
    	public final void testReadData() {
    		Tata.readData();
    	}
    }
    Je mets 2 points d'arrêts dans la classe du singleton, un au début de la méthode getSingleton et l'autre au niveau du System.out.println("pause");.

    Je commence par lancer mon test testPopulateData, il s'arrête dans la méthode getSingleton, comme c'est le premier appel il va le créer. Je continue l'execution il s'arrête au System.out.println("pause"). Je le laisse la a l'arrêt et je lance testReadData (création donc d'un nouveau thread), il s'arrête bien au début de la méthode getSingleton, seulement il me dit que MONTOTO est égal a null alors que je viens juste de le créer au dessus (et que quand je reviens au premier thread je vois bien sa valeur).


    Je ne comprends pas pourquoi j'ai ce résultat, et ce que je dois modifier pour que mon singleton marche bien.


    Merci

  2. #2
    Membre émérite
    Inscrit en
    Mars 2006
    Messages
    848
    Détails du profil
    Informations personnelles :
    Âge : 41

    Informations forums :
    Inscription : Mars 2006
    Messages : 848
    Par défaut
    Quand tu dis que tu lances un autre Thread, comment tu t'y prend exactement?

    T'es sûr de ne pas lancer le test dans une autre JVM?

  3. #3
    Modérateur
    Avatar de Alkhan
    Homme Profil pro
    ingénieur full stack
    Inscrit en
    Octobre 2006
    Messages
    1 232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : ingénieur full stack

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 232
    Par défaut
    bonjour,

    Ca commence mal ! l'implémentation de ton singleton est incorrect dans un contexte multithread, en effet !

    mais tu peux lire Le Singleton en environnement Multithread.
    Cela devrait te permettre de résoudre ton problème.
    Il n'y a pas de problème, il n'y a que des solutions.
    Cependant, comme le disaient les shadoks, s'il n'y a pas de solution, c'est qu'il n'y a pas de problème.
    Si toutefois le problème persiste, la seule solution restante est de changer le périphérique qui se trouve entre la chaise et l'écran

    Mes Articles : Mon premier article est sur le language D
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  4. #4
    Membre éprouvé Avatar de kain_tn
    Homme Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 833
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 833
    Par défaut
    A priori, tu lances ton deuxième thread dans une seconde JVM.

    Autre chose, perso, j'aurais fait comme ça pour un singleton multi-thread:
    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
     
     
    public class Toto{
     
    	private static Toto MONTOTO = null;
     
    	// Pas de synchronized (verrou) à part lors de la création de l'objet
    	public static Toto getSingleton(){
     
    		if(MONTOTO == null){
     
    			synchronized(Toto.class){
    				if(MONTOTO == null)
    					MONTOTO = new Toto();
    			}
    		}
     
    		return MONTOTO;
    	}
     
    	private Toto(){}
    }
    Une méthode synchronized, c'est plus lent en général, et puis là ça sert à rien mis à part pour l'initialisation:
    1. On test si l'objet est initialisé: si oui, on retourne l'instance, si non, on initialise
    2. On met en place le verrou
    3. On teste si l'objet est initialisé: supposons que deux threads concurrents entrent dans la première boucle, le premier thread crée l'objet pendant que le second attend l'acquisition du verrou. Sans la deuxième vérification, la première instance de l'objet est écrasée lorsque le deuxième thread obtient le verrou...


    (ah oui, et le constructeur en private c'est plus logique puisque l'instance est supposée être obtenue depuis la méthode statique getSingleton())


    EDIT:
    En fait il vaut mieux écrire (merci Alkhan):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
     
    public class Toto{
     
    	private static Toto MONTOTO = new Toto();
     
    	// Pas de synchronized (verrou) à part lors de la création de l'objet
    	public static Toto getSingleton(){
     
    		return MONTOTO;
    	}
     
    	private Toto(){}
    }

  5. #5
    Modérateur
    Avatar de Alkhan
    Homme Profil pro
    ingénieur full stack
    Inscrit en
    Octobre 2006
    Messages
    1 232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : ingénieur full stack

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 232
    Par défaut
    kain_tn, je pense en effet que tu as raison pour le lancement de 2 jvm différente en revanche, le code que tu donne fonctionne moins bien que celui d'alladdin.

    Celui d'alladdin a clairement un problème de cout avec la synchro mais le tiens ne garantie pas que le singleton sera pas instancier deux fois !

    Toi aussi lis Le Singleton en environnement Multithread.
    Il n'y a pas de problème, il n'y a que des solutions.
    Cependant, comme le disaient les shadoks, s'il n'y a pas de solution, c'est qu'il n'y a pas de problème.
    Si toutefois le problème persiste, la seule solution restante est de changer le périphérique qui se trouve entre la chaise et l'écran

    Mes Articles : Mon premier article est sur le language D
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #6
    Modérateur
    Avatar de Alkhan
    Homme Profil pro
    ingénieur full stack
    Inscrit en
    Octobre 2006
    Messages
    1 232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : ingénieur full stack

    Informations forums :
    Inscription : Octobre 2006
    Messages : 1 232
    Par défaut
    alladdin pendant que tu lis les docs regarde aussi Programmation des Threads en Java

    Tout devrait ensuite fonctionner
    Il n'y a pas de problème, il n'y a que des solutions.
    Cependant, comme le disaient les shadoks, s'il n'y a pas de solution, c'est qu'il n'y a pas de problème.
    Si toutefois le problème persiste, la seule solution restante est de changer le périphérique qui se trouve entre la chaise et l'écran

    Mes Articles : Mon premier article est sur le language D
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    Membre averti
    Inscrit en
    Décembre 2005
    Messages
    19
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 19
    Par défaut
    Merci beaucoup pour vos réponses et pour les pointeurs. En effet les tests étaient lances dans 2 JVM différentes (je lançais les test à partir d'éclipse, en allant sur debug du Junit test). J'ai pris le temps de lire le tuto sur les multithread, puis j'ai fais 2 thread basiques et le comportement cet fois est bien normal.

    Merci à tous .

  8. #8
    Membre éprouvé Avatar de kain_tn
    Homme Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 833
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 833
    Par défaut
    Citation Envoyé par Alkhan Voir le message
    kain_tn, je pense en effet que tu as raison pour le lancement de 2 jvm différente en revanche, le code que tu donne fonctionne moins bien que celui d'alladdin.
    .
    Ok, donc en fait le plus simple dans mon cas est d'utiliser l'initialisation statique.
    Pour ce qui est du volatile, je pensais que ça fonctionnait. Je ne pensais pas que c'était si dépendant de l'implémentation de la JVM.

    Merci

  9. #9
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    Citation Envoyé par kain_tn Voir le message
    Pour ce qui est du volatile, je pensais que ça fonctionnait. Je ne pensais pas que c'était si dépendant de l'implémentation de la JVM.
    En fait ça va plus loin que ça : que ça fonctionne ou pas dépend de la convention JMM suivie. Mais lorsque ça fonctionne, ça n'économise pas le coût d'une synchro.
    Dans un cas comme dans l'autre...
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

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

Discussions similaires

  1. Singleton et multithread
    Par totoche dans le forum Servlets/JSP
    Réponses: 2
    Dernier message: 25/05/2010, 18h05
  2. [Singleton] singleton et multithreading
    Par behess dans le forum Design Patterns
    Réponses: 17
    Dernier message: 24/09/2009, 18h33
  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