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

Java Discussion :

[Pattern]PB sur Singleton multi-thread


Sujet :

Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite
    Profil pro
    Architecte technique
    Inscrit en
    Mars 2002
    Messages
    966
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : Mars 2002
    Messages : 966
    Par défaut [Pattern]PB sur Singleton multi-thread
    Bonjour,

    Une petite question j'ai essayé d'implémenter un singleton avec la classe ThreadLocal malheureusement ça ne fonctionne pas correctement: plusieurs instances sont créées quand je lance une multitude de threads

    Où est l'erreur. Merci pour vos lumières:

    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
    public final class BeansPool {
      private static ThreadLocal<BeansPool> _singleton = new ThreadLocal<BeansPool>();
     
      /**
       * @return
       * @throws Exception 
       */
      public final static BeansPool getInstance() throws Exception {
          BeansPool pool = _singleton.get();
     
            if (pool == null) {
                System.out.println("New !!!");
                pool = new BeansPool();
                _singleton.set(pool);
            }
     
            return pool;
      }
    }
    A+

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    961
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 961
    Par défaut
    Citation Envoyé par thibaut
    plusieurs instances sont créées quand je lance une multitude de threads
    http://java.sun.com/j2se/1.4.2/docs/...readLocal.html

    Ca a l'air d'être précisément ce à quoi sert ThreadLocal.

  3. #3
    Membre émérite
    Profil pro
    Architecte technique
    Inscrit en
    Mars 2002
    Messages
    966
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : Mars 2002
    Messages : 966

  4. #4
    Membre émérite
    Avatar de divxdede
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    525
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2004
    Messages : 525
    Par défaut
    ThreadLocal est effectivement fait pour associer une valeur "potentiellement" differente à chaque threads de ton application.

  5. #5
    Membre expérimenté
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 194
    Par défaut
    Apparamment, ThreadLocal n'est pas synchronisé.
    L'instruction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    private static ThreadLocal<BeansPool> _singleton = new ThreadLocal<BeansPool>();
    requière un certain temps et deux threads peuvent l'appeler "simultanément", alors que l'autre n'a pas encore initialisé la variable. La variable est écrasée, mais si entre temps le premier thread a eu le temps de retourner l'objet qu'il a crée ...

    Il faut synchroniser l'initialisation des singletons dans un contexte multithreading.

    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
     
    public final class BeansPool {
      private static ThreadLocal<BeansPool> _singleton;
     
      /**
       * @return
       * @throws Exception 
       */
      public final static BeansPool getInstance() throws Exception {
          synchronized(ThreadLocal.class) {
               singleton = new ThreadLocal<BeansPool>();
          }
          BeansPool pool = _singleton.get();
     
            if (pool == null) {
                System.out.println("New !!!");
                pool = new BeansPool();
                _singleton.set(pool);
            }
     
            return pool;
      }
    }

  6. #6
    Membre expérimenté
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 194
    Par défaut
    La synchronisation de mes threads n'est pas bonne car, évidemment, il faudrait plutôt quelque chose comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    synchronized(ThreadLocal.class) {
          if(singleton == null)
                singleton = new ThreadLocal<BeansPool>();
          }
    }
    Mais l'essentiel est ailleurs. J'ai plutôt l'impression que ThreadLocal fais exactement l'inverse du contrat Singleton, enfin si j'ai bien compris. Il retourne autant d'objet que de thread

  7. #7
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    Pourquoi tu utilises ThreadLocal?

    Pourquoi ne pas faire simplement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public final class BeanPool {
     
        private static final BeanPool instance = new BeanPool();
     
        private BeanPool() { ... }
     
        public static BeanPool getBeanPool() {
            return instance;
        }
     
    }

  8. #8
    Membre émérite
    Profil pro
    Architecte technique
    Inscrit en
    Mars 2002
    Messages
    966
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : Mars 2002
    Messages : 966
    Par défaut
    Certes de cette façon ça marche... mais ce n'est pas ce que je veux tester.

  9. #9
    Membre expérimenté
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 194
    Par défaut
    Essayes un truc comme ça :
    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
     
    public class TestThreadLocal {
    	private static ThreadLocal<String> tl = new ThreadLocal<String>();
     
    	public String getSingleton() {
    		String s = tl.get();
    		if(s == null) {
    			s = Thread.currentThread().getName();
    			tl.set(s);
    		}
    		return s;
    	}
     
    	public static void main(String[] args) {
    		final TestThreadLocal test = new TestThreadLocal();
    		for(int i=0; i<20; i++) {
    			new Thread() {
    				public void run() {
    					System.out.println(test.getSingleton());
    					System.out.println(test.getSingleton());
    				}
    			}.start();
    		}
    	}
    }

  10. #10
    Expert confirmé
    Avatar de le y@m's
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2005
    Messages
    2 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2005
    Messages : 2 636
    Par défaut
    Citation Envoyé par ®om
    Pourquoi tu utilises ThreadLocal?

    Pourquoi ne pas faire simplement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public final class BeanPool {
     
        private static final BeanPool instance = new BeanPool();
     
        private BeanPool() { ... }
     
        public static BeanPool getBeanPool() {
            return instance;
        }
     
    }
    Tu as oublié de synchroniser la méthode static, ce qui est indispensable dans un contexte multithreads .

    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 final class BeanPool {
    
        private static final BeanPool instance = null;
    
        private BeanPool() { ... }
    
        public static synchronized BeanPool getBeanPool() {
            if(instance == null) {
                instance = new BeanPool();
            }
            return instance;
        }
    
    }
    Je ne répondrai à aucune question technique par MP.

    Pensez aux Tutoriels et aux FAQs avant de poster ;) (pour le java il y a aussi JavaSearch), n'oubliez pas non plus la fonction Rechercher.
    Enfin, quand une solution a été trouvée à votre problème
    pensez au tag :resolu:

    Cours Dvp : http://ydisanto.developpez.com
    Blog : http://yann-disanto.blogspot.com/
    Page perso : http://yann-disanto.fr

  11. #11
    Membre émérite
    Profil pro
    Architecte technique
    Inscrit en
    Mars 2002
    Messages
    966
    Détails du profil
    Informations personnelles :
    Âge : 52
    Localisation : France

    Informations professionnelles :
    Activité : Architecte technique

    Informations forums :
    Inscription : Mars 2002
    Messages : 966
    Par défaut
    Non c'est faux, car quand tu fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    private static final BeanPool instance = new BeanPool();
    Il semblerait que dans ce cas tu ne doives pas synchronizer ta méthode.

    Testé et approuvé.

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 15/11/2010, 14h21
  2. Singleton Multi Thread
    Par g_tarik0010 dans le forum C#
    Réponses: 7
    Dernier message: 18/06/2008, 11h12
  3. Aide sur Multi-Threading
    Par Fred2209 dans le forum Windows
    Réponses: 7
    Dernier message: 18/04/2007, 17h26
  4. Réponses: 5
    Dernier message: 14/04/2007, 14h12
  5. [XPATH] Erreur XPath sur du multi-thread
    Par pvoncken dans le forum Format d'échange (XML, JSON...)
    Réponses: 2
    Dernier message: 08/02/2006, 15h19

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