Exercice 1 : Gestion de parking
Question 1 : Effet de Semaphore(1) et Semaphore(4)
Dans la version initiale, Semaphore(1) signifie qu'une seule voiture
peut être dans le parking à un instant donné.
Si vous remplacez par Semaphore(4), jusqu'à 4 voitures pourront
accéder simultanément au parking (parallélisme jusqu'à 4
threads).
Question 2 : Effet de Semaphore(0)
Si vous initialisez le sémaphore à Semaphore(0), aucun thread ne
pourra entrer dans le parking car le compteur du sémaphore est
déjà à 0. Cela bloquera tous les appels à sem.P() dès qu'ils seront
invoqués.
Question 3 : Ajout d’une variable partagée pour le suivi des places
disponibles
Déclarez une variable static int N = 4; (nombre de places
disponibles).
Modifiez les méthodes InOutParking et P() pour afficher et
décrémenter N à l'entrée, puis l'incrémenter à la sortie. Assurez-
vous d’utiliser des blocs synchronisés pour garantir la cohérence
des accès à la variable N.
private synchronized void decrementerPlaces() {
N--;
[Link]("Places disponibles: " + N);
}
private synchronized void incrementerPlaces() {
N++;
[Link]("Places disponibles: " + N);
}
private void InOutParking() {
[Link]("Thread " + id + " entre dans le parking");
decrementerPlaces();
try { sleep((int) ([Link]() * 2000)); } catch
(InterruptedException e) {}
[Link]("Thread " + id + " sort du parking");
incrementerPlaces();
}
Exercice 2 : Dîner des philosophes
Problème de base
Chaque philosophe doit :
1. Penser ([Link] aléatoire).
2. Demander les fourchettes (exclusion mutuelle).
3. Manger ([Link] aléatoire).
4. Relâcher les fourchettes.
Pistes pour éviter famine et interblocage :
1. Un mutex pour chaque fourchette : Utilisez un tableau de
Semaphore pour représenter les fourchettes, initialisées à
1.
2. Protocole asymétrique pour éviter l’interblocage : Par
exemple, chaque philosophe peut prendre d’abord la
fourchette gauche, puis la droite, sauf le dernier
philosophe qui fait l’inverse.
Implémentation des classes Philo et Diner :
class Philo extends Thread {
private int id;
private Semaphore leftFork, rightFork;
public Philo(int id, Semaphore leftFork, Semaphore rightFork)
{
[Link] = id;
[Link] = leftFork;
[Link] = rightFork;
}
private void think() {
[Link]("Philo " + id + " pense");
try { sleep((int) ([Link]() * 2000)); } catch
(InterruptedException e) {}
}
private void eat() {
[Link]("Philo " + id + " mange");
try { sleep((int) ([Link]() * 2000)); } catch
(InterruptedException e) {}
}
public void run() {
while (true) {
think();
try {
[Link](); // Prendre la fourchette gauche
[Link](); // Prendre la fourchette droite
eat();
} catch (InterruptedException e) {
[Link]();
} finally {
[Link](); // Libérer la fourchette gauche
[Link](); // Libérer la fourchette droite
}
}
}
}
public class Diner {
public static void main(String[] args) {
int n = 5; // Nombre de philosophes
Semaphore[] forks = new Semaphore[n];
for (int i = 0; i < n; i++) forks[i] = new Semaphore(1);
Philo[] philosophers = new Philo[n];
for (int i = 0; i < n; i++) {
Semaphore leftFork = forks[i];
Semaphore rightFork = forks[(i + 1) % n];
philosophers[i] = new Philo(i, leftFork, rightFork);
philosophers[i].start();
}
}
}
Exercice 3 : Coiffeur dormeur
Contexte
Le problème représente une synchronisation entre un thread
coiffeur et plusieurs threads clients :
1. Le coiffeur dort quand il n'y a pas de clients.
2. Les clients attendent ou repartent si la salle d’attente est
pleine.
3. Le coiffeur réveille un client lorsqu’il termine une coupe.
Structure générale :
Sémaphores :
o ChaisesLibres : Contrôle les places dans la salle
d'attente.
o Reveiler : Réveille le coiffeur si nécessaire.
o ChaiseCoiffeur : Gère l’accès au fauteuil du coiffeur.
Implémentation des classes Client et Coiffeur :
class Client extends Thread {
private Semaphore ChaisesLibres, Reveiler, ChaiseCoiffeur;
public Client(String name, Semaphore chaisesLibres,
Semaphore reveiler, Semaphore chaiseCoiffeur) {
super(name);
[Link] = chaisesLibres;
[Link] = reveiler;
[Link] = chaiseCoiffeur;
}
public void run() {
try {
while (![Link]()) { // Attente d'une
place libre
[Link](getName() + " Salle pleine, je
reviendrai plus tard.");
sleep(5000);
}
[Link](getName() + " J'ai une place en salle
d'attente.");
[Link](); // Réveille le coiffeur si endormi
[Link](); // Attente de libération du
fauteuil
[Link](getName() + " En cours de coiffure.");
} catch (Exception e) {
[Link]();
}
}
}
class Coiffeur extends Thread {
private Semaphore Reveiler, ChaiseCoiffeur;
public Coiffeur(Semaphore reveiler, Semaphore
chaiseCoiffeur) {
[Link] = reveiler;
[Link] = chaiseCoiffeur;
}
public void run() {
while (true) {
try {
[Link]("Coiffeur en attente de client...");
[Link](); // Attente d'un client
[Link]("Client trouvé, prêt pour la
coiffure.");
[Link](); // Libérer le fauteuil
sleep(1000); // Temps de coiffure
[Link]("Coiffure terminée.");
} catch (Exception e) {
[Link]();
}
}
}
}
public class Salon {
public static void main(String[] args) {
int nbChaises = 3;
Semaphore ChaisesLibres = new Semaphore(nbChaises);
Semaphore Reveiler = new Semaphore(0);
Semaphore ChaiseCoiffeur = new Semaphore(0);
Coiffeur coiffeur = new Coiffeur(Reveiler, ChaiseCoiffeur);
[Link]();
for (int i = 0; i < 10; i++) {
new Client("Client " + i, ChaisesLibres, Reveiler,
ChaiseCoiffeur).start();
try { [Link](500); } catch (InterruptedException e)
{}
}
}
} class Client extends Thread {
private Semaphore ChaisesLibres, Reveiler, ChaiseCoiffeur;
public Client(String name, Semaphore chaisesLibres,
Semaphore reveiler, Semaphore chaiseCoiffeur) {
super(name);
[Link] = chaisesLibres;
[Link] = reveiler;
[Link] = chaiseCoiffeur;
}
public void run() {
try {
while (![Link]()) { // Attente d'une
place libre
[Link](getName() + " Salle pleine, je
reviendrai plus tard.");
sleep(5000);
}
[Link](getName() + " J'ai une place en salle
d'attente.");
[Link](); // Réveille le coiffeur si endormi
[Link](); // Attente de libération du
fauteuil
[Link](getName() + " En cours de coiffure.");
} catch (Exception e) {
[Link]();
}
}
}
class Coiffeur extends Thread {
private Semaphore Reveiler, ChaiseCoiffeur;
public Coiffeur(Semaphore reveiler, Semaphore
chaiseCoiffeur) {
[Link] = reveiler;
[Link] = chaiseCoiffeur;
}
public void run() {
while (true) {
try {
[Link]("Coiffeur en attente de client...");
[Link](); // Attente d'un client
[Link]("Client trouvé, prêt pour la
coiffure.");
[Link](); // Libérer le fauteuil
sleep(1000); // Temps de coiffure
[Link]("Coiffure terminée.");
} catch (Exception e) {
[Link]();
}
}
}
}
public class Salon {
public static void main(String[] args) {
int nbChaises = 3;
Semaphore ChaisesLibres = new Semaphore(nbChaises);
Semaphore Reveiler = new Semaphore(0);
Semaphore ChaiseCoiffeur = new Semaphore(0);
Coiffeur coiffeur = new Coiffeur(Reveiler, ChaiseCoiffeur);
[Link]();
for (int i = 0; i < 10; i++) {
new Client("Client " + i, ChaisesLibres, Reveiler,
ChaiseCoiffeur).start();
try { [Link](500); } catch (InterruptedException e)
{}
}
}
}