Bonjour à tous,

Tout d'abord un rapide descriptif de la situation :
  • Je code un jeu en client-serveur.
  • Dans ce jeu, chaque Joueur (une classe), lorsqu'il se connecte au serveur, se retrouve dans la liste de Joueur du GameManager (une classe).
  • Le GameManager et les Joueur tournent chacun dans leur propre thread.
  • Donc si on a 4 joueurs connectés, on aura 4 + 1 (le GameManager) = 5 threads qui tournent.


J'aimerais que le GameManager fasse la chose suivante :
  • Ne rien faire tant qu'un joueur ne l'a pas réveillé pour lui dire qu'il a changé d'état.
  • Lors du réveil par un joueur, exécuter des actions puis se rendormir jusqu'au prochain réveil


Je me suis intéressé au pattern Observer pour résoudre mon problème.
Celui-ci fonctionne très bien lorsque je n'ai qu'un thread, mais dès que j'essaye de l'adapter au multi-thread je me perds.

Voilà comment j'ai pensé les choses :
  • Les Joueur sont IObservable
  • Le GameManager est un IObserver
  • Chaque joueur possède le GameManager dans sa liste d'IObserver


En terme de code (simplifié) nous arrivons à la chose 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
15
class GameManager implements IObserver, Runnable {
  public void update() {
    // déclenchée lorsqu'un joueur réveille le thread
  }
 
  public void run() {
    // Boucle infinie se contentant d'attendre que le GameManager soit réveillé
    syncronized(this) {
      try {
        this.wait();
      }
      catch(...){...}
    }
  }
}
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 Joueur implements IObservable, Runnable {
  // Les méthodes permettant de gérer les observeurs
  public void addObserver(IObserver o){...}
  public void removeObserver(Iobserver o){...}
 
  public void notifyObservers() {
    // Itération parmi les IObserver et appel de la méthode update() (de l'interface IObserver)
  }
 
  public void run() {
    // Attente de la réception d'un message sur son socket
    // Dès que le message arrive, appel de notifyObservers()
  }
}
Ce que j'aimerai, c'est que le GameManager se réveille lors de l'appel d'un joueur, puis se rendorme, puis se réveille lors de l'appel d'un joueur etc.

Mais je ne sais pas où mettre les wait() et les notify() pour arriver à mes fins.

Dois-je mettre le notify() (permettant "d'annuler" le wait()) dans le notifyObservers() de Joueur ? Directement dans le update() de GameManager ?

Merci pour votre aide.