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 :

Java et les Threads


Sujet :

avec Java

  1. #1
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Novembre 2016
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 27
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Novembre 2016
    Messages : 8
    Points : 6
    Points
    6
    Par défaut Java et les Threads
    J'ai crée deux classes en Java ; la première classe intitulé Unthread étend de la classe Thread et la deuxième un main tout simplement .
    Je veux que l'utilisateur fait entrer à chaque tentative (il ya 5 tentatives) un mot pour une contrainte de temps de 8 sec et si le mot est correct la boucle while est interrompue sinon i=i+1 ; ( je fais le test du mot entré avec au autre mot ="akaichi")
    mon problème est : en faisant l'exécution à chaque tentative si j'entre rien et le temps est écoulé le programme ne passe pas a la ième tentative et il faut que je tape quelque chose au clavier pour qu'il passe à la tentative suivante .

    Je veux simplement que si aucun mot est entré et si le temps est écoulé il passe tout seul à la tentative suivante .

    Voilà la classe Unthread ;
    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 class Unthread extends Thread{
     
    	 public void run() {
     
    		 long time=0L;
    		 while (! isInterrupted())
    			{
    				time = System.currentTimeMillis();
    				try
    				{
    					// cinq secondes d'attente
    					Thread.sleep(8000);
    				}
    				catch (InterruptedException e)
    				{
    					//System.out.println("saisir votre mot");
    					// Activation du flag d'interruption
    					Thread.currentThread().interrupt();
    					break;
    				}
    				System.out.println("temps ecoulé");
    				break;
    }}}
    Voilà la classe main :
    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
    import java.util.Scanner;
     
    public class Main {
     
    	  public static void main(String[] args) throws Exception{
    		  Lire l =new Lire ();
    		 String tentative;
    		 int i=1;
    		 Boolean stop =false;
    		 while (i<=5 && stop==false){
    		 System.out.println("la valeur de i est "+" " +i);
    		  Unthread th=new Unthread();
    		  th.start();
    		  System.out.println("Saisir votre mot !");
    		// Attente d'une interruption manuelle  //System.in.read();
    	    tentative=l.chaine();//saisie 
    	    if (l.TestChaine(tentative))
    	    {stop=true;
    	    break;}
    		th.interrupt();
    		//
     
    		// Attente de la fin du thread
    		th.join();
     
    	 	if (i<5 )
    	 	System.out.println("Le mot est incorrect ! passons a la "+" "+(i+1)+" "+" ème tentative");
    		i=i+1;
     
    		 }
    Merci 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,

    1. Parlons d'abord de ton code

      • Code : Sélectionner tout - Visualiser dans une fenêtre à part
        1
        2
        3
        4
        5
        6
        catch (InterruptedException e) {
            //System.out.println("saisir votre mot");
            // Activation du flag d'interruption
            Thread.currentThread().interrupt();
            break;
        }
        Comme son nom l'indique currentThread() donne le thread courant, donc, l'instance de UnThread, celle pour laquelle le catch interruptedexception est en train de s'exécuter. En résumé, ce code dit qu'on "interrompt UnThread quand UnThread est interrompu", donc ça ne sert à rien.
        Je suppose que tu cherches à interrompre le thread principal, celui où on lit la réponse : pour faire ça, il va falloir que tu passes la référence de ce thread à UnThread :
        Code : Sélectionner tout - Visualiser dans une fenêtre à part
        1
        2
        Unthread th=new Unthread(Thread.currentThread());
        th.start();
        Ainsi, en la stockant dans un attribut de Unthread, tu pourras y avoir accès, et faire un interrupt() dessus.

      • Code : Sélectionner tout - Visualiser dans une fenêtre à part
        1
        2
        3
        4
        5
        th.interrupt();
        		//
         
        		// Attente de la fin du thread
        		th.join();
        Tu "interompts" le thread d'attente (UnThread). Puis ensuite tu attends que le thread d'attente soit terminé. Or, il a été "interrompu" et la gestion de cette interruption implique la terminaison du thread. Aucun intérêt d'attendre donc sa fin, qui a déjà eu lieu probablement.
      • Le dernier problème est relatif à l'implémentation de la classe Lire. Comme je ne la connais pas, difficile de dire ce qui va ou ne va pas. Toutefois, au sujet de la lecture du flux System.in, la plupart des méthodes étant bloquantes et non interruptible, il y a de forts risques que que l.chaine() soit bloquant, et donc que tout ton système ne fonctionne jamais (le programme attendra toujours qu'une saisie soit fournie avant de pouvoir continuer).


    2. La solution.
      Il y a une méthode non bloquante de InputStream qui peut aider : available(). Tu peux faire une boucle qui teste si available() est supérieur à 0, lire alors ce qu'il y a dans le buffer, le stocker dans ton propre buffer (un StringBuilder par exemple), jusqu'à ce qu'on ait un \r (touche entrée). Mais il faut que cette boucle laisse un peu de temps aux autres threads, ne serait-ce que pour interrompre le thread qui boucle, par un sleep() par exemple, ce qui te permettra en plus de choper l'InterruptedException et de gérer l'interruption de la saisie.
      A voir ce que la classe Lire te permet à ce niveau... es-tu obligé d'utiliser cette classe ?
      Par ailleurs, au lieu de ne se baser que sur l'état interrupted, j'utiliserai un flag qui permettrait de gérer de façon soft la boucle de lecture du clavier. Par exemple, un AtomicBoolean : le thread d'attente le passerait à true au bout du temps d'attente écoulé, et la boucle de lecture de System.in se ferait tant que ce booléen est faux.
      Enfin, je pense qu'il faut éviter de traiter la lecture dans le thread principal : avec 2 threads, tu auras plus de facilité à gérer leur cycle de vie, les enchaînement, lla gestion des états "interrompus", tout ça.
    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
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Novembre 2016
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 27
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Novembre 2016
    Messages : 8
    Points : 6
    Points
    6
    Par défaut
    @joel.drigo

    merci pour votre réponse

    j'ai utilisé System.in.read() pour la saisie du mot et cette méthode permet de lire seulement un caractère alors j'ai opté pour une classe Lire qui utilise cette méthode afin de lire toute une chaine (Tu trouves en dessous le code de la classe Lire ) .
    Je veux vous demander quelle est l’utilité d'un AtomicBoolean et comment l'utiliser je suis encore débutante en JAVA .

    Code java : 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
     
    public class Lire
    { 
    	private String nom ="akaichi";
    	// Cette fonction permet de saisir au clavier une variable de type String
    	// cette fonction se trouve au niveau de la classe joueur 
        public static String chaine()
        {
    	    String tmp = "";
    	    char C='\0';
    		try 
    		{
    			while ((C=(char) System.in.read()) !='\n')
    			{
    				if (C != '\r')  tmp = tmp+C;
     
    			}
    		}
    		catch (IOException e)
    		{
    			System.out.println("Erreur de frappe");
    			System.exit(0);
    		}
    		return tmp;
        } 
     
    public boolean TestChaine(String ch){
    boolean res;
    if (ch.equals(nom)){
    System.out.println("Bravo! Le mot est correct");
     
    res=true;}
    else res=false;
    return res;
     
     
    }}

  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
    La classe AtomicBoolean est un wrapper de boolean (une classe d'objets avec un attribut de type boolean) qui est implémenté de manière à permettre l'accès multi-thread facilement. Le second avantage est que comme c'est un objet, on peut le partager facilement entre plusieurs objets (un qui le modifira et l'autre le lira).

    Pour l'implémentation de la lecture, tu devrais penser que
    • si rien n'est dans le buffer, read retourne -1 (et non pas '\n'), et il ne faut surtout pas mettre ce caractère dans la saisie. Tu peux utiliser available() comme je te l'ai dit pour savoir si quelquechose (une saisie) est en attente de lecture dans le buffer. Il faut penser qu'on pourrait saisir plusieurs caractères plus vite que la boucle ne boucle, donc avoir plusieurs caractères dans le buffer.
    • il serait judicieux d'utiliser un StringBuilder plutôt que de concaténer les caractères lus dans tmp (mais ce n'est pas très grave dans ton cas, seulement c'est une bonne habitude à prendre). Et tu devrais avoir un moyen de différencier le cas où la saisie est annulée avec qu'on ait pu saisir aucun caractère. Taper entrée (donc saisir une chaîne vide) est une saisie de chaîne vide, alors que si on arrête la lecture avant toute frappe tmp est aussi vide : 2 cas identiques pour 2 raisons différentes. Un boolean par exemple permettra de faire la différence.
    • je t'ai dit de laisser un peu de temps dans la boucle pour les autres threads (avec un sleep() sur un temps très court). Aussi, il faut penser surtout à gérer l'interruption du thread dans cette boucle : justement, avec un sleep, tu auras une InterruptedException qui te permettra de savoir qu'il faut sortir de la boucle.

    La boucle de lecture devrait être plutôt du genre
    Code pseudocode : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    tant qu'il faut lire (on teste ici l'AtomicBoolean
        s'il y a quelque chose à lire (test de available)
            on flag qu'on a lu au moins un caractère
            tant qu'il y a des octets dans le buffer (tant que read!=-1)
                 si le caractère lu est la touche entrée (\n) on sort des deux boucles
                 on concatène les caractères affichables (>=' ') correspondant dans le buffer de lecture
            fin tant que
       fin si
       on attend (appel de sleep()) un petit peu pour laisser du temps aux autres threads de pouvoir prendre la main (et en cas d'interruption de cette attente on sort de la boucle)
    fin tant que
    si le flag de lecture est à true, on a lu quelque chose
       donc on retourne le contenu du buffer de lecture
    sinon
       on retourne null
    fin si

    Lorsque le thread de timeout arrive au timeout il passe l'AtomicBoolean à true et appelle interrupt sur le thread qui fait cette boucle de lecture.

    [edit]j'ai oublié un truc : if (C != '\r') tmp = tmp+C; il ne faut pas prendre en compte dans tmp tous les caractères non affichable (comme par exemple \t), donc fait plutôt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (C>= ' ')  tmp = tmp+C;
    ...
    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.

  5. #5
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Novembre 2016
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 27
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Novembre 2016
    Messages : 8
    Points : 6
    Points
    6
    Par défaut
    Merci énormément vous m'avez beaucoup aidé

  6. #6
    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
    C'est bon alors... tu as un programme qui fonctionne ? Si c'est le cas, ce qui serait bien pour ceux qui viendraient sur ce forum à la recherche d'une solution au même problème puissent voir ta solution, et que tu marques par ailleurs la discussion comme résolue.
    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. java et les thread
    Par gentelmand dans le forum Général Java
    Réponses: 13
    Dernier message: 23/09/2009, 09h49
  2. Les Threads en java
    Par opensource dans le forum Débuter
    Réponses: 11
    Dernier message: 06/03/2009, 09h52
  3. les threads en java
    Par karimala dans le forum Général Java
    Réponses: 2
    Dernier message: 29/12/2008, 14h45
  4. les threads en java
    Par t.n.b.g dans le forum Général Java
    Réponses: 3
    Dernier message: 31/01/2008, 17h48
  5. Mandriva est il faché avec les thread java?
    Par Flophx dans le forum Applications et environnements graphiques
    Réponses: 2
    Dernier message: 29/12/2007, 12h09

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