Vous êtes sur la page 1sur 6

U NIVERSITÉ DE J ENDO UBA

I NSTITUT S UP É RIEUR D E L’I NF ORM ATI QU E DU K EF

TP 5 : "les Threads"

Matière : Développement d’applications réparties Niveau : 3 eme LSI


Responsable : Hanen Samaali A U : 2023 / 2024

Exercice 1 :
// Import de la classe Thread pour créer des threads
class Compteur extends Thread {
// Déclaration des variables membres pour le compteur
protected int count, inc, delay, Nit;

// Constructeur de la classe Compteur


public Compteur(int init, int inc, int delay, int Nit){
this.count = init; // Initialisation du compteur avec une valeur initiale
this.inc = inc; // L'incrément à ajouter/soustraire à chaque itération
this.delay = delay; // Le temps de pause entre chaque itération
this.Nit = Nit; // Le nombre total d'itérations à effectuer
}

// La méthode run() est exécutée lorsque le thread est démarré


public void run(){
try {
for (int i = 0; i < Nit; i++) {
System.out.println(count + " "); // Affichage de la valeur actuelle
du compteur
count += inc; // Ajout ou soustraction de l'incrément
sleep(delay); // Pause pour simuler une interruption
}
} catch(InterruptedException e){}
}
}

// Classe Threads pour le programme principal

class Threads {
public static void main(String[] args) {
// Création et démarrage de deux threads Compteur avec des paramètres
différents
new Compteur(0, 1, 30, 10).start(); // Premier thread, incrémente de 1,
pause de 30 ms
new Compteur(0, -1, 100, 10).start(); // Deuxième thread, décrémente de 1,
pause de 100 ms
}
}

Exercice 2 :
// Classe CompteBancaire pour représenter un compte bancaire
class CompteBancaire {
private int valeur; // Solde du compte

1
// Constructeur de la classe CompteBancaire
public CompteBancaire(int valeur) {
this.valeur = valeur; // Initialisation du solde
}

// Méthode synchronisée pour retirer de l'argent du compte


//le type de retour boolean permet de transmettre l'information sur le
succès ou l'échec du retrait,
public synchronized boolean retirerArgent(int montant, String nom) {
if (montant <= valeur) {
valeur -= montant; // Réduction du solde
System.out.println(nom + " a retiré " + montant); // Affichage de
la transaction
return true; // Retrait réussi
} else {
System.out.println("Solde insuffisant pour " + nom); // Affichage
en cas de solde insuffisant
return false; // Retrait échoué
}
}
}

// Classe Compteur qui représente un thread effectuant des retraits sur un


compte bancaire
class Compteur extends Thread {
private CompteBancaire compte; // Référence vers le compte bancaire
private String nom; // Nom du thread (tata ou toto)
private int montant; // Montant du retrait

// Constructeur de la classe Compteur


public Compteur(CompteBancaire compte, String nom, int montant) {
this.compte = compte; // Initialisation de la référence vers le compte
this.nom = nom; // Initialisation du nom du thread
this.montant = montant; // Initialisation du montant du retrait
}

// Méthode exécutée lorsque le thread est démarré


public void run() {
if (compte.retirerArgent(montant, nom)) {
//La méthode retirerArgent renvoie un booléen (true si le retrait a
réussi, false sinon).
// Le thread vérifie le résultat à l'aide d'une instruction if.

}
}
}

// Classe principale Threads pour l'exécution du programme


class Threads {
public static void main(String[] args) {
CompteBancaire compte = new CompteBancaire(100); // Création du compte
bancaire avec un solde initial de 100

// Création de deux threads (tata et toto) qui effectuent des retraits


sur le même compte
Compteur tata = new Compteur(compte, "tata", 20);
Compteur toto = new Compteur(compte, "toto", 20);

tata.start(); // Démarrage du thread tata


toto.start(); // Démarrage du thread toto
}
}

2
Exercice 3 :
// Classe Station pour gérer les usagers et le bus
class Station {
private boolean busWaiting = false; // Indique si un bus est en attente

// Méthode pour les usagers attendent un bus


public synchronized void attendreBus() {
while (!busWaiting) {
try {
wait(); // L'usager attend qu'un bus arrive
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // Gestion de l'interruption
}
}
}

// Méthode appelée par le bus lorsqu'il est prêt à charger les usagers
public synchronized void chargerUsagers() {
busWaiting = false; // Le bus est parti, plus de bus en attente
notifyAll(); // Réveille tous les threads usagers en attente
}

// Méthode appelée par le bus lorsqu'il arrive à la station


public synchronized void busArrive() {
busWaiting = true; // Un bus est en attente
notifyAll(); // Réveille les threads usagers pour signaler l'arrivée du bus
}
}

// Classe Usager pour simuler les usagers


class Usager extends Thread {
private String nom; // Nom de l'usager
private Station s; // Station associée à l'usager
private int heureArrivee; // Heure d'arrivée de l'usager

public Usager(String nom, Station s, int heureArrivee) {


this.nom = nom;
this.s = s;
this.heureArrivee = heureArrivee;
}

public void run() {


try {
sleep(heureArrivee); // Simulation de l'heure d'arrivée de l'usager
System.out.println(nom + " arrive à la station");
s.attendreBus(); // L'usager attend un bus
System.out.println(nom + " est monté dans le bus");
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // Gestion de l'interruption
}
}
}

// Classe Bus pour simuler le bus


class Bus extends Thread {
private Station s; // Station associée au bus
private int heureArrivee; // Heure d'arrivée du bus

public Bus(Station s, int heureArrivee) {


this.s = s;
this.heureArrivee = heureArrivee;
}

3
public void run() {
try {
sleep(heureArrivee); // Simulation de l'heure d'arrivée du bus
System.out.println("Bus arrive à la station");
s.busArrive(); // Le bus est prêt à charger des usagers
Thread.sleep(500); // Attente pour que les usagers montent à bord
s.chargerUsagers();
System.out.println("Bus repart de la station");
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // Gestion de l'interruption
}
}
}

// Classe principale pour exécuter la simulation


class BusSimple {
public static void main(String args[]) {
Station Gare = new Station(); // Crée une instance de la station

Bus b7 = new Bus(Gare, 2000); // Crée un bus qui arrive après 2000 ms

// Crée des usagers avec différents noms et heures d'arrivée


Usager u[] = {// un tableau d'objets "Usager" est créé. Chaque élément du
tableau est une instance de la classe "Usager
new Usager("Philippe", Gare, 1500),
new Usager("Patricia", Gare, 3000),
new Usager("Yves", Gare, 1000),
new Usager("Mireille", Gare, 1000)
};

b7.start(); // Démarre le thread du bus

for (Usager usager : u) {// La boucle for est utilisée pour itérer à travers
le tableau d'usagers et effectuer une opération sur chaque usager.
usager.start(); // Démarre les threads des usagers
}
}
}

Exercice 4:

import java.util.LinkedList;

// Classe pour représenter le tampon d'objets partagé


class TabObject {
private LinkedList<Integer> buffer = new LinkedList<>(); // Une liste chaînée
pour stocker les objets
private int capacity; // Capacité maximale du tampon
private int totalItemsProduced = 0; // Nombre total d'objets produits

public TabObject(int capacity) {


this.capacity = capacity; // Initialisation de la capacité du tampon
}

// Méthode pour produire un objet et le placer dans le tampon


public synchronized void produce(int item) throws InterruptedException {
while (buffer.size() == capacity) {
wait(); // Attendre si le tampon est plein
}
buffer.add(item);

4
totalItemsProduced++;

System.out.println("Produit : " + item); // Affichage de la production


notifyAll(); // Réveiller les threads en attente
}

// Méthode pour consommer un objet du tampon


public synchronized int consume(String name) throws InterruptedException {
while (totalItemsProduced < 5 && buffer.isEmpty()) {
wait(); // Attendre si le tampon est vide et que la production n'est pas
terminée
}
if (buffer.isEmpty()) {
return -1; // Retourner -1 si le tampon est vide
}

int item = buffer.removeFirst(); // Retirer le premier objet du tampon


notifyAll(); // Réveiller les threads en attente
return item;
}
}

// Classe pour le thread producteur


class Producteur extends Thread {
private TabObject tabObject;

public Producteur(TabObject tabObject) {


this.tabObject = tabObject;
}

public void run() {


for (int i = 0; i < 5; i++) {
try {
tabObject.produce(i); // Appeler la méthode de production du tampon
Thread.sleep(30); // Pause entre les productions (simulation)
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // Gestion de l'interruption en
cas d'erreur
}
}
}
}

// Classe pour le thread consommateur


class Consommateur extends Thread {
private TabObject tabObject;
private String name;
private int pause; // Temps de pause entre les consommations (simulation)

public Consommateur(TabObject tabObject, String name, int pause) {


this.tabObject = tabObject;
this.name = name;
this.pause = pause;
}

public void run() {


while (true) {
try {
int item = tabObject.consume(name); // Appeler la méthode de
consommation du tampon
if (item != -1) {
System.out.println(name + " a consommé : " + item); // Afficher
la consommation
sleep(pause); // Pause entre les consommations (simulation)
5
} else {
break;
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // Gestion de l'interruption en
cas d'erreur
}
}
}
}

// Classe principale
class ProducteurConsommateur {
public static void main(String[] args) throws InterruptedException {
TabObject tabObject = new TabObject(3); // Créer un tampon avec une capacité
de 3 éléments

Producteur producteur = new Producteur(tabObject); // Créer le thread


producteur associé au tampon
Consommateur consommateur1 = new Consommateur(tabObject, "Consommateur 1",
40); // Créer le thread consommateur 1 avec une pause de 40 ms
Consommateur consommateur2 = new Consommateur(tabObject, "Consommateur 2",
40); // Créer le thread consommateur 2 avec une pause de 40 ms

producteur.start(); // Démarrer le thread producteur


consommateur1.start(); // Démarrer le thread consommateur 1
consommateur2.start(); // Démarrer le thread consommateur 2
}
}

Vous aimerez peut-être aussi