La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

Multi-Thread Jian-Yun Nie

Présentations similaires


Présentation au sujet: "Multi-Thread Jian-Yun Nie"— Transcription de la présentation:

1 Multi-Thread Jian-Yun Nie
IFT1025 – Programmation 2 Multi-Thread Jian-Yun Nie

2 Concepts Thread: Processus en parallèle
Unité de programme qui est exécuté en parallèle avec le reste des programmes Processus en parallèle Plusieurs processus sont exécutés en même temps Créer, lancer et terminer un thread Interface Runnable Synchronisation des threads

3 Interface Runnable Une méthode run() exigée: Implantation:
public interface Runnable { void run(); } Implantation: public class MyRunnable implements Runnable public void run() // Task statements go here . . .

4 Créer un thread Un Thread est une classe qui implante Runnable
1. Créer une sous-classe de Thread (doit aussi implanter run() ) class PrimeThread extends Thread { long minPrime; PrimeThread(long minPrime) { this.minPrime = minPrime; } public void run() { // compute primes larger than minPrime . . . Utilisation: PrimeThread p = new PrimeThread(143); p.start();

5 Créer un thread 2. Un thread est créé à base d’un objet Runnable
Runnable r = new MyRunnable(); Thread t = new Thread(r); t.start();

6 Classe Thread public class Thread extends Object implements Runnable
Constructeurs: Thread() Thread(Runnable target) Thread(String name)

7 Classe Thread Méthodes:
static int activeCount(): nb. de threads de ce groupe void destroy() void interrupt() static void sleep(long millis) void start() static void yield(): faire une pause et permettre aux autres threads d’exécuter (traitement de deadlock)

8 Explication de thread Séquence d’actions Bien ordonnée en parallèle

9 Exemple1: Définition de Thread
Créer une sous-classe de Thread: public class SimpleThread extends Thread { public SimpleThread(String str) { super(str); } public void run() { for (int i = 0; i < 10; i++) { System.out.format("%d %s%n", i, getName()); try { sleep((long)(Math.random() * 1000)); } catch (InterruptedException e) {} System.out.format("DONE! %s%n", getName()); Thread avec un nom Méthode run(): 10 fois: Afficher le nom du Thread et sleep un temps aléatoire

10 Exemple1: Utilisation du Thread
Lancer 2 Threads public class TwoThreadsTest { public static void main (String[] args) { new SimpleThread("Jamaica").start(); new SimpleThread("Fiji").start(); }

11 Différence avec un appel à run()
public class TwoThreadsTest { public static void main (String[] args) { new SimpleThread("Jamaica").run(); new SimpleThread("Fiji").run(); } 0 Jamaica 1 Jamaica 2 Jamaica 3 Jamaica 4 Jamaica 5 Jamaica 6 Jamaica 7 Jamaica 8 Jamaica 9 Jamaica DONE! Jamaica 0 Fiji 1 Fiji 2 Fiji 3 Fiji 4 Fiji 5 Fiji 6 Fiji 7 Fiji 8 Fiji 9 Fiji DONE! Fiji

12 Exemple 2: Clock start de Applet stop: si la fenêtre ferme
Tant que non-fini, reffiche toute les secondes import java.awt.*; import java.util.*; import java.applet.*; import java.text.*; public class Clock extends java.applet.Applet implements Runnable { private volatile Thread clockThread = null; DateFormat formatter; //Formats the date displayed String lastdate; //String to hold date displayed Date currentDate; //Used to get date to display Color numberColor; //Color of numbers Font clockFaceFont; Locale locale; public void init() { setBackground(Color.white); numberColor = Color.red; locale = Locale.getDefault(); formatter = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.MEDIUM, locale); currentDate = new Date(); lastdate = formatter.format(currentDate); clockFaceFont = new Font("Sans-Serif", Font.PLAIN, 14); resize(275, 25); } public void start() { if (clockThread == null) { clockThread = new Thread(this, "Clock"); clockThread.start(); public void run() { Thread myThread = Thread.currentThread(); while (clockThread == myThread) { repaint(); try { Thread.sleep(1000); } catch (InterruptedException e){ } } public void paint(Graphics g) { String today; currentDate = new Date(); formatter = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.MEDIUM, locale); today = formatter.format(currentDate); g.setFont(clockFaceFont); //Erase and redraw g.setColor(getBackground()); g.drawString(lastdate, 0, 12); g.setColor(numberColor); g.drawString(today, 0, 12); lastdate = today; currentDate = null; public void stop() { clockThread = null; Temps courant start de Applet stop: si la fenêtre ferme start de Thread – run()

13 Déclarer Thread avec Thread ou Runnable?
1. Créer une sous-classe de Thread 2. Créer un Thread avec Runnable Les 2 méthodes sont possibles Utiliser la 2-ième méthode si le Thread doit être une sous-classe d’une autre classe (e.g. Clock) La première méthode ne le permet pas Une classe ne peut pas avoir 2 super-classes

14 États d’un Thead Création et lancement: Entrer dans Runnable
public void start() { if (clockThread == null) { clockThread = new Thread(this, "Clock"); clockThread.start(); } Entrer dans Runnable Not Runnable: sleep(), E/S Dead: terminaison: Fermer Applet -> exécuter stop() public void stop() { //applet's stop method clockThread = null;

15 Terminer un Thread Schéma typique: public void run() { try
for (int i = 1; i <= REPETITIONS; i++) // Do work } catch (InterruptedException exception) // Clean up

16 Exemple Sortie? 1, 3, 4 public class MyRunnable implements Runnable {
public void run() try System.out.println(1); Thread.sleep(1000); System.out.println(2); } catch (InterruptedException exception) System.out.println(3); System.out.println(4); Sortie? 1, 3, 4

17 Détecter l’état d’un Thread
Thread.getState(): NEW RUNNABLE BLOCKED WAITING TIMED_WAITING TERMINATED

18 Synchronisation Accès conflictuels: écrire lire
X +2 -100 *1.02 -20 Accès conflictuels: écrire lire (put - producer) (get -consumer)

19 Exemple: Accéder au même BankAcount
public class DepositRunnable implements Runnable { public void run() try for (int i = 1; i <= count; i++) account.deposit(amount); Thread.sleep(DELAY); } catch (InterruptedException exception) public class WithdrawRunnable implements Runnable { public void run() try for (int i = 1; i <= count; i++) account.withdraw(amount); Thread.sleep(DELAY); } catch (InterruptedException exception)

20 Problème new DepositRunnable().start();
new WithdrawRunnable().start(); Depositing 100.0, new balance is 100.0 Withdrawing 100.0, new balance is 0.0 . . . Withdrawing 100.0, new balance is 400.0 Depositing 100.0, new balance is 500.0 Withdrawing 100.0, new balance is 300.0 Problème Depositing Withdrawing 100.0, new balance is 100.0, new balance is

21 Synchronisation: Solution 1
Bloquer la ressource durant un traitement: public class BankAccount { public BankAccount() balanceChangeLock = new ReentrantLock(); . . . } private Lock balanceChangeLock; Utilisation typique: balanceChangeLock.lock(); Code that manipulates the shared resource balanceChangeLock.unlock();

22 Utilisation typique Toujours dans BankAccount
public void deposit(double amount) { balanceChangeLock.lock(); try System.out.print("Depositing " + amount); double newBalance = balance + amount; System.out.println(", new balance is " + newBalance); balance = newBalance; } finally balanceChangeLock.unlock(); Finally: Pour que ça fonctionne même si une exception est lancée

23 Interface Lock void lock(): bloquer la ressource
Condition newCondition(): associer une condition (plus tard) void unlock(): débloquer Les classes qui implante l’interface Lock: ReentrantLock, ReentrantReadWriteLock.ReadLock, ReentrantReadWriteLock.WriteLock

24 Schéma général Bloquer Exécuter un bloc (try) Débloquer (finally)
Lock l = ...; l.lock(); try { // access the resource protected by this lock } finally { l.unlock(); }

25 ReentrantLock Une classe qui implante Lock
Plus de méthodes que celles exigées dans Lock class X { private final ReentrantLock lock = new ReentrantLock(); // ... public void m() { lock.lock(); // block until condition holds try { // ... method body } finally { lock.unlock()

26 Synchronisation: Solution 2
synchronized: réalise block, try [bloc], finally {unlock} public class BankAccount { public synchronized void deposit(double amount) System.out.print("Depositing " + amount); double newBalance = balance + amount; System.out.println(", new balance is " + newBalance); balance = newBalance; } public synchronized void withdraw(double amount) System.out.print("Withdrawing " + amount); double newBalance = balance - amount;

27 Problème de Deadlock 2 ou plus Threads attendent qu’un autre thread débloque une ressource nécessaire Possède A Demande B Possède B Demande C Possède C Demande A

28 Une solution à Deadlock (façon 1)
Objet Condition associé à un Lock public class BankAccount { public BankAccount() //Constructeur balanceChangeLock = new ReentrantLock(); sufficientFundsCondition = balanceChangeLock.newCondition(); . . . } private Lock balanceChangeLock; private Condition sufficientFundsCondition;

29 Une solution à Deadlock
Un retrait attend la condition nécessaire public void withdraw(double amount) { balanceChangeLock.lock(); try while (balance < amount) sufficientFundsCondition.await(); . . . } finally balanceChangeLock.unlock();

30 Effets de await() sufficientFundsCondition.await();
Attendre la ressource nécessaire (suffisamment d’argent) Relâche l’objet bloqué en attendant (BankAccount) Permet aux autres threads d’exécuter L’attente se réveille quand il reçoit un signal – signalAll()

31 Une solution à Deadlock
Un retrait attend la condition nécessaire public void withdraw(double amount) { balanceChangeLock.lock(); try while (balance < amount) sufficientFundsCondition.await(); . . . // faire le retrait } finally balanceChangeLock.unlock(); Le thread attend, relâche l’objet BankAcount, attend d’être signalé (ou interrompu) Quand il est signalé, on doit tester encore la condition balance < amount

32 Une solution à Deadlock
Un dépôt signale à tous les Thread que la condition est possiblement changée public void deposit(double amount) { balanceChangeLock.lock(); try System.out.print("Depositing " + amount); double newBalance = balance + amount; System.out.println(", new balance is " + newBalance); balance = newBalance; sufficientFundsCondition.signalAll(); } finally balanceChange.unlock();

33 Condition Construction à partir d’un Lock: Méthodes de Condition:
Lock.newCondition() Méthodes de Condition: void await(): attend d’être signalé ou interrompu void signal(): réveille un thread qui attend void signalAll(): réveille tous les threads qui attendent

34 Résumé class Ressource { Lock l; Condition c = l.newCondition();
public void methode1 //consumer { l.lock(); try { while (…) c.await(); … } finally {l.unlock();} } public void methode2 //producer { l.lock(); try { …, signalAll(); } finally {l.unclock(); Méthode qui attend une condition Méthode qui peut satisfaire ne condition d’un autre thread

35 Sortir de Deadlock (façon 2)
Thread.yield() static void yield(); Pause du thread courant, et permet aux autres threads d’exécuter Utilisation typique Si le thread ne dispose qu’une partie de resource, et l’autre partie n’est pas disponible: relâcher la ressource retenu (la rendre disponible) Thread.yield(); // permet aux autres d’exécuter

36 Les méthodes dans Object
Les méthodes de Object permettent aussi de synchroniser les threads: void wait(): attendre void notify(): signale un Thread qui attend qu’il y a eu un changement void notifyAll(): signale à tous les Threads

37 Exemple de deadlock Les deux méthodes bloquent
public synchronized int get() { //Won't work! if (available == true) { available = false; return contents; } public synchronized void put(int value) { //Won't work! if (available == false) { available = true; contents = value;

38 Solution à Deadlock (façon 3)
public synchronized int get() { while (available == false) { try { //Wait for Producer to put value. wait(); } catch (InterruptedException e) { } } available = false; //Notify Producer that value has been retrieved. notifyAll(); return contents; public synchronized void put(int value) { while (available == true) { try { //Wait for Consumer to get value. wait(); } catch (InterruptedException e) { } } contents = value; available = true; //Notify Consumer that value has been set. notifyAll(); Tant que la condition n’est pas vraie, wait(): - met le thread en attente, - permet aux autres threads d’exécuter notifyAll(): réveille tous ceux qui wait()


Télécharger ppt "Multi-Thread Jian-Yun Nie"

Présentations similaires


Annonces Google