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

Concurrence et multi-thread Java Discussion :

thread perd la main entre 2 sleep()


Sujet :

Concurrence et multi-thread Java

  1. #1
    Membre du Club
    Inscrit en
    Avril 2006
    Messages
    57
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 57
    Points : 43
    Points
    43
    Par défaut thread perd la main entre 2 sleep()
    Bonjour,

    Cela fait bien longtemps que je n'ai pas programmé avec des threads, et je suis effrayé de voir à quel point j'ai (presque) tout oublié!
    Peut-être pourrez-vous m'aider?

    Mon programme utilise plusieurs threads d'une même classe, qui est définie de cette façon:
    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 MonThread{
       ...
       public void run() {
          while (condition) do {
             instructions_A; //appel de méthodes d'autres classes
             ...
             sleep(2000);
             ...
             instructions_B; //ecriture dans 1 fichier partagé par               tous les threads
          }
       }
       ...
    }
    Ma question: est-ce que lorsqu'un de mes threads a la main, je peux être sûr qu'il continuera son exécution sans interruption jusqu'à l'instruction sleep?
    Dans ce cas je n'aurai pas besoin d'utiliser des méthodes/mot clés "synchronized"!

    Merci d'avance pour votre aide,

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 802
    Points : 653
    Points
    653
    Par défaut
    Non, tu n'as aucune garantie que ton thread s'exécutera d'affiler, sans interruption, et il n'y a aucun moyen d'obtenir ce résultat.

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    572
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Février 2007
    Messages : 572
    Points : 675
    Points
    675
    Par défaut
    Citation Envoyé par Nicool Voir le message
    Ma question: est-ce que lorsqu'un de mes threads a la main, je peux être sûr qu'il continuera son exécution sans interruption jusqu'à l'instruction sleep?
    Non, absolument pas. Ton thread peut être interrompu à n'importe quel moment.

    Citation Envoyé par Nicool Voir le message
    Dans ce cas je n'aurai pas besoin d'utiliser des méthodes/mot clés "synchronized"!
    Ca dépend de ce que tu veux proteger ...

  4. #4
    Membre averti
    Inscrit en
    Juin 2003
    Messages
    292
    Détails du profil
    Informations forums :
    Inscription : Juin 2003
    Messages : 292
    Points : 317
    Points
    317
    Par défaut
    Citation Envoyé par Nicool Voir le message
    Bonjour,

    Cela fait bien longtemps que je n'ai pas programmé avec des threads, et je suis effrayé de voir à quel point j'ai (presque) tout oublié!
    Peut-être pourrez-vous m'aider?

    Mon programme utilise plusieurs threads d'une même classe, qui est définie de cette façon:
    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 MonThread{
       ...
       public void run() {
          while (condition) do {
             instructions_A; //appel de méthodes d'autres classes
             ...
             sleep(2000);
             ...
             instructions_B; //ecriture dans 1 fichier partagé par               tous les threads
          }
       }
       ...
    }
    Ma question: est-ce que lorsqu'un de mes threads a la main, je peux être sûr qu'il continuera son exécution sans interruption jusqu'à l'instruction sleep?
    Dans ce cas je n'aurai pas besoin d'utiliser des méthodes/mot clés "synchronized"!

    Merci d'avance pour votre aide,
    je crois que ca ne sera pas possible sans synchronisation ou bien tu peux utiliser des join plustot pour etre sur que Thread2 attend que le Thread1 termine son execution.

    cheers

  5. #5
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,

    Non : il n'y a aucun moyen de s'assurer que le thread conserve la main. Cela dépend entièrement de l'ordonnanceur du système d'exploitation et cela peut varier d'une exécution à l'autre...


    Et pour rappel le mot-clef synchronized ne permet pas de "conserver" la main mais de synchronizé les accès à une ressource en utilisant un verrou sur une référence (un seul thread par verrou)

    a++

    [edit] triplement grillé sur ce coup

  6. #6
    Membre du Club
    Inscrit en
    Avril 2006
    Messages
    57
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 57
    Points : 43
    Points
    43
    Par défaut
    Merci c'est très sympa à vous de m'avoir répondu si vite
    C'est drôle j'ai parcouru tutoriaux et FAQ, on y lit l'intérêt de la synchronisation, des sleep et autre wait...
    cependant je n'avais rien trouvé sur la NECESSITE de ladite synchronisation.

    Bon, dans mon cas ce que je dois "protéger" c'est l'écriture dans mon fichier (XML) partagé par les différents threads (chaque thread doit écrire quelque chose à chaque tour de boucle). Il ne faut pas qu'un thread commence à écrire dans le fichier alors que le précédent n'a pas fini d'écrire ses balises XML...

    Que pensez vous de cette solution:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    instructions_B { // cf. mon 1er post
       ...
       ClasseUtilitaire.ecrireDansFichierPartage(texteAEcrire);
       ...
    }
    avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public class ClasseUtilitaire {
       ...
       public static synchronized void ecrireDansFichierPartage(String aEcrire) {
          ... // ecriture de balises XML dans le fichier partagé
       }
       ...
    }
    Est-ce que cette solution vous parait fiable?

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    802
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 802
    Points : 653
    Points
    653
    Par défaut
    Si tu connais le nombre de threads qui travaillent de concert sur ton fichier XML, tu peux utiliser un CyclicBarrier.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    final CyclicBarrier barrier = new CyclicBarrier(nb, new Runnable() {
    	public void run() {
    		//code à exécuter lorsque la barrière est déverouillée
    	}
    });
     
    new Thread() {
    	@Override
    	public void run() {
    		//traitement
    		barrier.await();
    	}
    }
    La méthode await() doit être appelée nb fois pour déverrouiller la barrière.

  8. #8
    Membre actif

    Homme Profil pro
    Software Engineer
    Inscrit en
    Août 2004
    Messages
    173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Software Engineer
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Août 2004
    Messages : 173
    Points : 220
    Points
    220
    Par défaut
    Pourquoi ne pas utiliser simplement un mutex sur la tache qui se sert du fichier XML en écriture ?
    C'est dans la classe ReentrantLock , tu protèges (c'est à dire ferme l'accès) avec objet.lock(); et ré-ouvre avec objet.unlock ();

    Au vu de ton code ca ma l'air le plus simple

  9. #9
    Membre confirmé
    Inscrit en
    Mai 2007
    Messages
    335
    Détails du profil
    Informations forums :
    Inscription : Mai 2007
    Messages : 335
    Points : 524
    Points
    524
    Par défaut
    Citation Envoyé par Nicool Voir le message
    Que pensez vous de cette solution:
    avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public class ClasseUtilitaire {
       ...
       public static synchronized void ecrireDansFichierPartage(String aEcrire) {
          ... // ecriture de balises XML dans le fichier partagé
       }
       ...
    }
    Est-ce que cette solution vous parait fiable?
    moi ça me parait fiable. Evidemment un Mutex ou un sémaphore ferais également l'affaire, mais pourquoi personne ne propose directement l'utilisation du synchronized, ça sert à ça ????

  10. #10
    Membre du Club
    Inscrit en
    Avril 2006
    Messages
    57
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 57
    Points : 43
    Points
    43
    Par défaut
    En tout cas merci pour vos multiples réponses!

    La solution d'Vivian Pennel me paraît bien: je ne connaissais pas le mutex. Ce qui me chagrinait avec le synchronized, c'est que j'ai peur que l'objet fichier soit dévérouillé si je fais appel à une autre méthode non-synchronisée au sein de ma méthode synchronisée...

    Je vais clore la discussion puisque ma question initiale a eu moult réponses. Merci encore!

  11. #11
    Membre éclairé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    572
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Février 2007
    Messages : 572
    Points : 675
    Points
    675
    Par défaut
    Citation Envoyé par Nicool Voir le message
    La solution d'Vivian Pennel me paraît bien: je ne connaissais pas le mutex. Ce qui me chagrinait avec le synchronized, c'est que j'ai peur que l'objet fichier soit dévérouillé si je fais appel à une autre méthode non-synchronisée au sein de ma méthode synchronisée...
    L'utilisation de synchronised ou des mutex est dans ton cas equivalent. Il n'y aura pas de relachement du verrou si tu appelles une methode non synchronized.

    Sauf que l'utilisation des mutex demande une plus grande attention. Notamment le relachement du mutex doit etre place dans un bloc finally

    Tu n'as donc a priori aucune raison d'utiliser les mutex au lieu de synchronized.

    Par contre, si tu veux juste proteger l'ecriture du fichier, tu peux toujours regarder du cote de FileLock.

  12. #12
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Nicool Voir le message
    La solution d'Vivian Pennel me paraît bien: je ne connaissais pas le mutex. Ce qui me chagrinait avec le synchronized, c'est que j'ai peur que l'objet fichier soit dévérouillé si je fais appel à une autre méthode non-synchronisée au sein de ma méthode synchronisée...
    Le Mutex (ou plus exactement les Lock) font exactement la même chose que les bloc synchronized, et il n'y a pas de problème de "perte" du verrou avec les deux méthodes mais il faut bien réfléchir à ce qui doit être synchronisé et ce qui ne l'est pas...

    a++

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

Discussions similaires

  1. communication entre un std::thread et le main
    Par robinsondesbois dans le forum Threads & Processus
    Réponses: 5
    Dernier message: 17/04/2014, 16h44
  2. Thread, reprendre la main après un sleep
    Par Invité1 dans le forum Concurrence et multi-thread
    Réponses: 5
    Dernier message: 07/04/2008, 21h55
  3. Réponses: 2
    Dernier message: 29/04/2007, 19h59
  4. [Infos] Différence entre Tread.sleep et wait
    Par ederf dans le forum Langage
    Réponses: 6
    Dernier message: 25/07/2006, 17h54
  5. problème : je perds la main
    Par rhum_un dans le forum Autres Logiciels
    Réponses: 2
    Dernier message: 18/10/2005, 17h32

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