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

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

Présentations similaires


Présentation au sujet: "1 IFT1025 – Programmation 2 Multi-Thread Jian-Yun Nie."— Transcription de la présentation:

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

2 2 Concepts Thread: –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 3 Interface Runnable Une méthode run() exigée: public interface Runnable { void run(); } Implantation: public class MyRunnable implements Runnable { public void run() { // Task statements go here... }

4 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 5 Créer un thread 2. Un thread est créé à base dun objet Runnable Runnable r = new MyRunnable(); Thread t = new Thread(r); t.start();

6 6 Classe Thread public class Thread extends ObjectObject implements RunnableRunnable Constructeurs: ThreadThread() ThreadThread(Runnable target)Runnable ThreadThread(String name)String …

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

8 8 Explication de thread Séquence dactions Bien ordonnée en parallèle

9 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 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 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 12 Exemple 2: Clock 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; } start de Applet start de Thread – run() stop: si la fenêtre ferme Temps courant Tant que non-fini, reffiche toute les secondes

13 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 dune autre classe (e.g. Clock) –La première méthode ne le permet pas –Une classe ne peut pas avoir 2 super-classes

14 14 États dun Thead Création et lancement: 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 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 16 Exemple 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 17 Détecter létat dun Thread Thread.getState(): –NEW –RUNNABLE –BLOCKED –WAITING –TIMED_WAITING –TERMINATED

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

19 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 20 Depositing 100.0, new balance is Withdrawing 100.0, new balance is 0.0 Depositing 100.0, new balance is Withdrawing 100.0, new balance is Withdrawing 100.0, new balance is Depositing 100.0, new balance is Withdrawing 100.0, new balance is Withdrawing 100.0, new balance is Problème Depositing Withdrawing 100.0, new balance is 100.0, new balance is new DepositRunnable().start(); new WithdrawRunnable().start();

21 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 22 Utilisation typique 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(); } Toujours dans BankAccount Finally: Pour que ça fonctionne même si une exception est lancée

23 23 Interface Lock void lock(): bloquer la ressourcelock Condition newCondition(): associer une condition (plus tard)newCondition void unlock(): débloquerunlock Les classes qui implante linterface Lock: ReentrantLockReentrantLock, ReentrantReadWriteLock.ReadLock, ReentrantReadWriteLock.WriteLock ReentrantReadWriteLock.ReadLock ReentrantReadWriteLock.WriteLock

24 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 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 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; System.out.println(", new balance is " + newBalance); balance = newBalance; } …

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

28 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 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 30 Effets de await() sufficientFundsCondition.await(); Attendre la ressource nécessaire (suffisamment dargent) Relâche lobjet bloqué en attendant (BankAccount) –Permet aux autres threads dexécuter Lattente se réveille quand il reçoit un signal – signalAll()

31 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 lobjet BankAcount, attend dêtre signalé (ou interrompu) Quand il est signalé, on doit tester encore la condition balance < amount

32 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 33 Condition Construction à partir dun Lock: –Lock.newCondition() Méthodes de Condition: –void await(): attend dêtre signalé ou interrompuawait –void signal(): réveille un thread qui attendsignal –void signalAll(): réveille tous les threads qui attendentsignalAll

34 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 dun autre thread

35 35 Sortir de Deadlock (façon 2) Thread.yield() –static void yield(); –Pause du thread courant, et permet aux autres threads dexécuter Utilisation typique –Si le thread ne dispose quune partie de resource, et lautre partie nest pas disponible: relâcher la ressource retenu (la rendre disponible) Thread.yield(); // permet aux autres dexécuter

36 36 Les méthodes dans Object Les méthodes de Object permettent aussi de synchroniser les threads: –void wait(): attendrewait –void notify(): signale un Thread qui attend quil y a eu un changementnotify –void notifyAll(): signale à tous les ThreadsnotifyAll

37 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 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 nest pas vraie, wait(): - met le thread en attente, - permet aux autres threads dexécuter notifyAll(): réveille tous ceux qui wait()


Télécharger ppt "1 IFT1025 – Programmation 2 Multi-Thread Jian-Yun Nie."

Présentations similaires


Annonces Google