Salut à tous

Ma question n'est pas compliquée mais seul les plus motivés liront mon problème en entier (merci d'avance ).

Voici la question :
Est ce correct de faire comme ça ?

Mon problème :
J'ai 2 composants et un "client". Mon client est un thread et fait des requêtes au premier composant "Controleur" qui lui même est un Thread et fait des requêtes au composant "Porte" qui est aussi un Thread.

J'ai volontairement simplifier le problème. Le cheminement est expliqué en commentaire mais n'hésitez pas à poser des questions

Ma première class est le Main qui lance le Client :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
package testthread;
 
public class TestThread
{
    public static void main(String[] args)
    {
        Client lui = new Client();
        lui.start();
    }
}
Ensuite vient la class Client :
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package testthread;
 
import java.util.logging.Level;
import java.util.logging.Logger;
 
public class Client extends Thread
{
    /**
     * Le thread client agit sur le controleur :
     */
    private Controleur c;
 
    public Client()
    {
        //J'instancie le Controleur dans le constructeur de Client :
        c = new Controleur();
    }
 
    @Override
    public void run()
    {
        //Le client run, donc je peux lancer mon controleur :
        c.start();
        System.out.println("Client launched =)");
        int i = 0;
        while(true)
        {
            //Le client s'execute...
            execution();
            //...puis envoie des requetes au controleur avec un entier en paramètre
            //(on pourra penser à faire un protocole en chaine de caractère) :
            System.out.println("Le client fait une requete au controleur et envoie " + i);
            c.requete(i);
            i++;
        }
    }
 
    synchronized private void execution()
    {
        try
        {
            this.sleep(2000);
        }
        catch(InterruptedException ex)
        {
            Logger.getLogger(Porte.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

Le composant Controleur :
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package testthread;
 
import java.util.EmptyStackException;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;
 
public class Controleur extends Thread
{
    /**
     * Sous Thread :
     */
    private Porte porte;
    /**
     * Pile de requetes
     */
    private Stack<Integer> pile;
 
    public Controleur()
    {
        porte = new Porte();
        pile = new Stack<Integer>();
    }
 
    @Override
    public void run()
    {
        System.out.println("Controleur launched =)");
        porte.start();
        while(true)
        {
            if(!pile.empty())
            {
                //On prend la requete en attente :
                Integer req;
                synchronized(pile)
                {
                    req = pile.pop();
                }
                //On execute :
                execution();
                System.out.println("Le controleur pop " + req);
                //On fait une requete sur un autre composant :
                porte.requete(req);
            }
            else
            {
                try
                {
                    //Si la pile de requete est vide, on fait dormir le thread :
                    synchronized(this)
                    {
                        System.out.println("--------------------- Le Controleur wait !");
                        this.wait();
                    }
                }
                catch(InterruptedException ex)
                {
                    Logger.getLogger(Controleur.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }
 
    synchronized public void requete(int requete)
    {
        //On stoque la requete :
        pile.push(requete);
        System.out.println("Le controleur push " + requete);
        //On reveille le thread pour qu'il traite la requete dans le run :
        System.out.println("--------------------- Le Controleur est notify !");
        this.notify();
    }
 
    /**
     * Fonction permettant d'executer durant 200 ms
     */
    private void execution()
    {
        try
        {
            this.sleep(800);
        }
        catch(InterruptedException ex)
        {
            Logger.getLogger(Porte.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

Le composant Porte :
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package testthread;
 
import java.util.EmptyStackException;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;
 
public class Porte extends Thread
{
    private Stack<Integer> pile;
 
    public Porte()
    {
        pile = new Stack<Integer>();
    }
 
    @Override
    public void run()
    {
        System.out.println("Porte launched =)");
        while(true)
        {
            if(!pile.empty())
            {
                //On prend la requete en attente :
                Integer req;
                synchronized(pile)
                {
                    req = pile.pop();
                }
                //On execute :
                System.out.println("La porte pop " + req);
                execution();
            }
            else
            {
                try
                {
                    //Si la pile de requete est vide, on fait dormir le thread :
                    synchronized(this)
                    {
                        System.out.println("--------------------- La porte wait !");
                        this.wait();
                    }
                }
                catch(InterruptedException ex)
                {
                    Logger.getLogger(Porte.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }
 
    synchronized public void requete(int requete)
    {
        //On stoque la requete :
        pile.push(requete);
        System.out.println("La porte push " + requete);
        //On reveille le thread pour qu'il traite la requete :
        System.out.println("--------------------- La porte est notify !");
        this.notify();
    }
 
    private void execution()
    {
        try
        {
            this.sleep(800);
        }
        catch(InterruptedException ex)
        {
            Logger.getLogger(Porte.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

Voici l’exécution pour mieux comprendre :
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
31
32
33
34
35
36
37
38
Client launched =)
Controleur launched =)
--------------------- Le Controleur wait !
Porte launched =)
--------------------- La porte wait !
Le client fait une requete au controleur et envoie 0
Le controleur push 0
--------------------- Le Controleur est notify !
Le controleur pop 0
La porte push 0
--------------------- La porte est notify !
--------------------- Le Controleur wait !
La porte pop 0
--------------------- La porte wait !
Le client fait une requete au controleur et envoie 1
Le controleur push 1
--------------------- Le Controleur est notify !
Le controleur pop 1
La porte push 1
--------------------- La porte est notify !
--------------------- Le Controleur wait !
La porte pop 1
--------------------- La porte wait !
Le client fait une requete au controleur et envoie 2
Le controleur push 2
--------------------- Le Controleur est notify !
Le controleur pop 2
La porte push 2
--------------------- La porte est notify !
--------------------- Le Controleur wait !
La porte pop 2
--------------------- La porte wait !
Le client fait une requete au controleur et envoie 3
Le controleur push 3
--------------------- Le Controleur est notify !
Le controleur pop 3
La porte push 3
--------------------- La porte est notify !

Ça fonctionne correctement mais je ne suis pas sur que ça soit très conventionnel de faire des "this.wait()" et "this.notify()" quoique... c'est plutôt propre à mon sens !?

Merci