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 :

Les Threads et les méthodes wait() & notify()


Sujet :

Java

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2019
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2019
    Messages : 5
    Points : 3
    Points
    3
    Par défaut Les Threads et les méthodes wait() & notify()
    Bonjour à tous,

    Je suis actuellement en DUT Informatique (1ère année) et j'ai découvert la programmation événementielle en Java, ce domaine m'intéressant beaucoup et ayant l'envie de progresser, je me suis lancé dans la conception d'un Memory avec la bibliothèque de JavaFx pour développer ce projet.
    Pour mettre en place ce jeu, j'ai eu besoin d'utiliser le multi-threading car je ne pouvais pas faire afficher les deux cartes sélectionnés par l'utilisateur un court instant avant qu'elle soient de nouveau cachés, malheureusement je n'ai jamais étudié cela en cours, c'est donc "à l'aveugle" que je me suis lancé sur cette idée. Seulement je rencontre un problème, je faisais apparaître un nouveau thread a chaque clic ce qui était redondant, inutile et consommateur de performance pour pas grand-chose au final.
    J'ai donc décidé de déclarer seulement un autre thread lors de l'apparition de la scène, et de "mettre en pause" celui-ci avec wait(), puis, lorsque je clic sur une carte je notifie ce thread avec notify(). Mais cela ne fonctionne pas, et malgré les cours, les vidéos que j'ai lu/vu je ne comprends pas clairement le fonctionnement de la méthode wait() et notify() ainsi que la synchronisation qui doit faire "verrou" si j'ai bien suivi.
    C'est pourquoi je viens vers vous afin que vous puissiez m'expliquer plus clairement le fonctionnement des méthodes wait() et notify() svp.


    Merci beaucoup pour votre aide,
    Stry.

  2. #2
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Le soucis c'est que je ne comprends pas trop le besoin d'utiliser Thread, wait() et notify() dans un environnement JavaFX alors qu'il y a tout ce qu'il faut dans le toolkit ui pour éviter justement de le faire (ex : dans ton cas PauseTransition et des écouteurs divers et variés).

    EDIT - de plus si tu te met a faire un wait() en plein milieu du JavaFX Application Thread (le thread principal JavaFX) ben tu bloques complètement tout ton UI donc plus rien de nouveau ne s'affichera ou répondre aux saisies utilisateur.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  3. #3
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2019
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2019
    Messages : 5
    Points : 3
    Points
    3
    Par défaut
    Je me suis renseigné sur la classe PauseTransition et j'ai déclaré une PauseTransition dans ma méthode qui est appelé lorsque que je clic sur une carte.
    Ma méthode se lance donc, elle passe ma carte en rouge par exemple, elle vérifie si ma condition est vraie et si c'est le cas, elle déclare PauseTransition pause = new PauseTransition(Duration.millis(3000)); et la déclenche avec pause.play(); puis après (toujours dans la méthode) je fais un for each et je passe toutes le cartes visibles en blanc.
    Seulement, lorsque je lance mon programme et que je clic sur une seconde carte, il passe directement la première carte sélectionnée en blanc et ne modifie la deuxième carte sur laquelle je viens de cliquer (elle reste en blanc).
    Je ne sais pas si c'est que la vue n'affiche que le "résultat" ou si l'erreur viens d'ailleurs, dîtes-moi si vous avez besoin que je vous montre mon code pour plus de clarté.

    Merci beaucoup pour votre aide,
    Stry.

  4. #4
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Euh oui ou du moins des extraits car là je n'ai absolument rien compris à ce que tu essaies de faire et j'ai aussi l'impression que ce n'est pas clair pour toi, par exemple :

    elle déclare PauseTransition pause = new PauseTransition(Duration.millis(3000)); et la déclenche avec pause.play(); puis après (toujours dans la méthode) je fais un for each et je passe toutes le cartes visibles en blanc.
    PauseTransition c'est pour exécuter une action après (via son setOnFinished()), c'est pas fait pour figer le programme et comme je disais plus haut de toute manière figer le programme c'est pas un truc à faire !
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  5. #5
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2019
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2019
    Messages : 5
    Points : 3
    Points
    3
    Par défaut
    Voici deux extraits du code qui pourront t'aider j'espère :

    Ce qu'il se passe quand on clique sur une carte :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    static class TournerCarte implements EventHandler<MouseEvent>{
     
    		@Override
    		public void handle(MouseEvent event) {
     
    			if(event.getSource() == carte1) {
     
    				carte1.setFill(Color.RED);	// Toutes les cartes sont par défaut en blanc.
    				cartes_visible.add(carte1); // Lorsqu'on sélectionne une carte, celle-ci change de couleur de fond 	
    				this.verifierParite();			
    			}
    La méthode verifierParite() :

    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
    private void verifierParite() {
     
    			if(2 == Jeu.cartes_visible.size()) { // On vérifie d'abord que l'utilisateur a bien cliqué sur deux cartes
     
    				PauseTransition pause = new PauseTransition(Duration.millis(5000000));
     
    								// À partir de là, je suis perdu je voudrais qu'il y ait  un court instant (2sec) durant laquelle l'utilisateur
    				pause.play();	        // voit les cartes qu'il a retournées avant de les retourner (repasser en blanc)
     
    				for(Rectangle carte : Jeu.cartes_visible) {
     
    					carte.setFill(Color.WHITE);
     
    				}
    				Jeu.cartes_visible.clear(); 
    			}
     
    		}
    J'espère que ça pourra t'éclairer, dis-moi si tu as besoin d'éléments supplémentaires.
    Concernant le fait que la pause va faire buguer mon programme voir planter, je comprends mais je vois pas trop comment réaliser ce que je viens de t'expliquer sans mettre en pause le programme. Je vais chercher une solution alternative en espérant en trouver une.

    Stry.

  6. #6
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Bon visiblement il te manque quelques fondamentaux en UI donc je vais tenter une explication généraliste de comment ça marche (c-a-d en gros le concept général, donc les détails peuvent varier suivant le toolkit). AWT/Swing et JavaFX tournent sur un thread unique, appelé l'EDT (Event Dispatch Thread) et JavaFX Application Thread pour l'un ou l'autre. Ce thread unique alterne entre la propagation d'événement et le rendu graphique (pas totalement vrai pour JavaFX mais je ne vais pas rentrer dans les détails) et il s'agit du thread dans lequel par exemple tu réagis aux actions sur les boutons. Ce thread ne doit JAMAIS être stoppé ou ralenti trop longtemps par une action de longue durée.

    Chaque toolkit dispose d'API permettant de faire des taches longues en fond (ex : lire des gros fichiers sur le disque, accéder au réseau ou à une base de donnée), dans JavaFX c'est le couple Service<T>/Task<T> mais ce n'est pas ce qui va t'aider ici puisque toi tu cherches à faire une animation graphique. Pour cela JavaFX propose 3 manières de faire :
    • Timeline qui permet de construire des animations très complexes en disposant des actions clé (KeyFrame) à intervalles de temps réguliers qui permettent de faire des animations interpolées en prenant une valeur (KeyValue) de départ et une autre de fin et en calculant automatiquement les positons intermédiaires.
    • Transition et toutes ses classes filles qui reprend le même principe mais avec des classes prêtes à l'emploi beaucoup plus simples à utiliser.
    • AnimationTimer qui permet de se créer un timer qui représente la bouche principale dans un jeu vidéo (en gros, le cœur qui fait battre le temps dans le monde du jeu)


    Dans ton cas tu as créé un jeu simple en utilisant un modèle événementiel (ce qui est largement suffisant pour un jeu de carte); tu as juste besoin d'une petite animation pour afficher puis cacher des cartes. Cela peut se modéliser simplement avec une ou plusieurs Transition ou une Timeline (mais qui peut être bien plus complexe à coder). Ici je vais partir du principe que tu n'as pas encore d'animation qui retourne la carte (le fait de retourner visuellement la carte - voir ici), elle a juste deux états, visible et pas visible.

    Cela peut donc se faire de la manière suivante :

    • Afficher les cartes
    • Démarrer une pause
      • Quand la pause se termine, cacher les cartes


    Ce qui peut se coder de la manière suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // Éventuellement interdire les interactions utilisateur ici.
    [...]
    // Afficher les cartes ici.
    [...]
    // Préparer la pause
    final var pause = new PauseTransition(Duration.millis(5000000));
    pause.setOnFinished(event -> {
        // Cacher les cartes ici.
        [...]
        // Éventuellement autoriser les interactions utilisateur ici.
        [...]
    });
    // Lancer l'animation.
    pause.play()
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  7. #7
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2019
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2019
    Messages : 5
    Points : 3
    Points
    3
    Par défaut
    Bonjour,

    Désolé pour la réponse tardive, j'ai réussi à faire ce que je voulais grâce à vous, merci beaucoup.

    Avant de passer le sujet en résolu, j'ai une dernière question : j'ai vu (dans l'exemple que vous me proposiez) que vous aviez déclaré final var pause = new PauseTransition(Duration.millis(50000));. Je n'ai jamais vus qu'on pouvait déclarer une variable avec var en Java (je suis sur Java 8 pour les cours) du coup je me suis renseigné un peu sur cette déclaration et je comprends mieux d'où ça vient mais concrètement, quelle est l'utilité de déclarer une variable final var au lieu de final PauseTransition par exemple ?

    Merci encore pour votre aide.
    Stry.

  8. #8
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Le mot-clé var : est utilisable en Java depuis le JDK 10, c'est pour cela que tu ne l'as jamais rencontré auparavant puisque tu es encore en JDK 8. C'est juste pour être un poil plus concis comme tous les languages qui supportent ce genre de notation. Cette notation est optionnelle et ça ne change pas grand chose par rapport au fait de déclarer le type exacte de la variable.

    Le mot-clé final : c'est juste de la bonne pratique pour éviter de réaffecter la variable quand ce n'est pas nécessaire. C'est aussi optionnel dans le sens où rien au niveau des IDE ou du language te force à l'utiliser mais, comme la déclaration des paramètre d'une méthode en final, cela peut parfois éviter de faire des effets de bord non prévus.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  9. #9
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2019
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 24
    Localisation : France, Haute Vienne (Limousin)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2019
    Messages : 5
    Points : 3
    Points
    3
    Par défaut
    Très bien, je connaissais déjà pour le mot-clé final mais un petit rappel ne fait pas mal !

    Merci pour votre aide tout au long de cette conversation.
    Stry

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

Discussions similaires

  1. Réponses: 3
    Dernier message: 02/07/2013, 09h04
  2. Thread et utilisation de wait() et notify()
    Par K-you dans le forum Général Java
    Réponses: 6
    Dernier message: 13/04/2010, 11h19
  3. [Thread] différence entre les méthodes start/run
    Par maetalkrio dans le forum Débuter avec Java
    Réponses: 3
    Dernier message: 20/10/2009, 17h06
  4. [Interface] Appeller toutes les méthodes héritées d'un class
    Par thibaut.d dans le forum Général Java
    Réponses: 4
    Dernier message: 25/01/2005, 08h42
  5. Utiliser les méthodes des boutons crées en rafale.
    Par kabouns dans le forum Composants
    Réponses: 8
    Dernier message: 03/12/2004, 10h48

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