TP 1 – Threads

Exercice 1

1. Ecrire une classe Compteur qui possède un nom et qui compte jusqu’à n en affichant à chaque fois son nom et le nombre en cours, dans une fonction « public void run()« .

Il marque une pause aléatoire entre chaque nombre (de 0 à 2000 millisecondes par exemple).
Une fois terminé il indique qu’il a terminé (toujours en affichant son nom).

2. Dans la fonction main, lancez plusieurs compteurs à la suite. Que se passe-t-il ? (évident)

public class Compteur01 {

	private String nom;
	private int max;

	public Compteur01(String nom, int max) {
		super();
		this.nom = nom;
		this.max = max;
	}

	public void run() {
		for (int i=1; i<this.max; i++) {
			System.out.println(this.nom+" "+i);
			try {
				Thread.sleep((int) (Math.random() * 2000));
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.println(this.nom+" terminé.");
	}

	public static void main(String[] args) {
		Compteur01 c1=new Compteur01("Bob",8);
		Compteur01 c2=new Compteur01("Jon",8);
		c1.run();
		c2.run();
	}

}

3. Modifier la classe pour en faire un thread (attention il ne fait plus appeler directement la méthode run()).

public class Compteur02 extends Thread {

	private String nom;
	private int max;

	public Compteur02(String nom, int max) {
		super();
		this.nom = nom;
		this.max = max;
	}

	public void run() {
		for (int i=1; i<this.max; i++) {
			System.out.println(this.nom+" "+i);
			try {
				Thread.sleep((int) (Math.random() * 2000));
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.println(this.nom+" terminé.");
	}

	public static void main(String[] args) {
		Compteur02 c1=new Compteur02("Bob",8);
		Compteur02 c2=new Compteur02("Jon",8);
		c1.start();
		c2.start();
	}

}

4. Ajouter une ligne pour afficher « Tout est terminé », à la fin de la méthode main. Que se passe-t-il ?

...
		c1.start();
		c2.start();
		System.out.println("Tout est terminé.");

Comment faire ?

...
		c1.start();
		c2.start();
		try {
			c1.join();
			c2.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("Tout est terminé.");
	}

}

5. Le langage JAVA propose le mécanisme des interfaces. Modifiez ce programme pour implémenter l’interface Runnable au lieu d’hériter de Thread.

Exercice 2

On donne la classe suivante, qui permet de gérer le solde d’un compte bancaire, en effectuant des débits et des crédits.

public class CompteBancaire {
	  private int solde = 0;

	  public int getSolde() {
	    return solde;
	}

	public void debite(int op) {
	  System.out.println("Débit de "+op);
	  this.solde-=op;
	}

	public void credite(int op) {
	  System.out.println("Crédit de "+op);
	  this.solde+=op;
	}
}

La classe OperationNulle lance un ou plusieurs threads qui exécutent des opérations s’annulant (crédit puis débit de la même somme).

public class OperationsNulles extends Thread {

	private CompteBancaire compte;
	private static int nbTh = 20;
	private int ID ;

	public OperationsNulles(CompteBancaire compte, int i) {
		super();
		this.compte = compte;
		this.ID=i;
	}

	public void run() {
		while (true) {
			int s = (int) (Math.random() * 1000);
			compte.credite(s);
			compte.debite(s);
			System.out.println("solde "+compte.getSolde()+ " (opération "+this.ID+")");
		}
	}

	public static void main(String[] args) {
		CompteBancaire compte = new CompteBancaire();
		OperationsNulles operations[]=new OperationsNulles[nbTh];
		for (int i = 0; i < nbTh; i++) {
			operations[i] = new OperationsNulles(compte,i);
			operations[i].start();
		}
	}

}

Que se passe-t-il lorsqu’on lance plusieurs de ces threads en même temps ?
Comment corriger.

	public void run() {
		while (true) {
			int s = (int) (Math.random() * 1000);
			synchronized (compte) {
				compte.credite(s);
				compte.debite(s);
			}
			System.out.println("solde "+compte.getSolde()+ " (opération "+this.ID+")");
		}
	}

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *