Composants threadés avec requête via Pile
Salut à tous :)
Ma question n'est pas compliquée mais seul les plus motivés liront mon problème en entier (merci d'avance :mouarf:).
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:
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:
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:
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:
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:
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 :aie: