Scaricare la presentazione
La presentazione è in caricamento. Aspetta per favore
PubblicatoFranco Basso Modificato 9 anni fa
1
Priorità e Sincronizzazione tra Threads
2
Priorità e preemption Java non garantisce la preemption Lo scheduling avviene in base all’algortimo Highest Priority First Un thread interrompe l’esecuzione se: –Esce dal proprio metodo run() –Si sospende invocando sleep(), wait() oppure è in attesa di I/O –Cede la CPU invocando yield() –Entra nel sistema un thread a priorità maggiore
3
Se il thread etra nello stato Not Runnable, vi è sempre una specifica modalità per tornare nello stato Runnable : Se il thread è stato disposto nello stato di sleep(), dopo che un determinato numero di millisecondi è terminato. Se il thread è in stato di wait(), si attende che un altro oggetto notifichi la condizione al thread in attesa con notify() o notifyAll(). Altri dettagli in Synchronizing Threads. Se un thread è bloccato in I/O, occorre attendere che l’I/O completi Un thread entra nello stato Not Runnable se uno dei seguenti eventi si verifica: Il metodo sleep è invocato. Il thread chiama il metodo wait in attesa che una specifica condizione sia soddisfatta. Il thread è bloccato in I/O. sleep((long)(Math.random() * 1000));
4
public void run() { for (int i = 0; i < 10; i++) { System.out.println(i + " " + getName()); try { sleep((long)(Math.random() * 1000)); } catch (InterruptedException e) {} } System.out.println("DONE! " + getName()); } Un programma non ferma un thread come avviene con un Applet attraverso la chiamata di un metodo. Un thread provoca la propria morte attraverso la terminazione naturale del metodo run. Causa la pausa temporanea del thread correntemente in esecuzione e permette ad altri thread di essere eseguiti. Metodo isAlive Il metodo isAlive restituisce true se il thread è in stato Runnable o Not Runnable. Se il metodo isAlive restituisce false, il thread è un nuovo thread oppure è morto. Non è possibile distinguire tra un nuovo thread e un thread morto e tra un thread Runnable e un thread Not Runnable.
5
CPU Scheduler ThreadThread 1 Un thread a più alta priorità diventa runnable. Il thread yields, oppure il suo metodo run termina Su sistemi che supportano partizione di tempo, la frazione di tempo allocata è terminata Thread 1 Thread Priority Thread 2 PREEMPTION esegue il thread con più alta priorità Quando il thread si ferma, yields, o diventa Not Runnable, un thread a più bassa priorità inizierà l’esecuzione Se due thread con stessa priorità sono in attesa di essere eseguiti, lo scheduler li esegue con politica round-robin. fixed priority scheduling. priority
6
The Java runtime will not preempt the currently running thread for another thread of the same priority. In other words, the Java runtime does not time-slice. However, the system implementation of threads underlying the Java Thread class may support time-slicing. Do not write code that relies on time-slicing. In addition, a given thread may, at any time, give up its right to execute by calling the yield method. Threads can only yield the CPU to other threads of the same priority--attempts to yield to a lower priority thread are ignored. When all the runnable threads in the system have the same priority, the scheduler chooses the next thread to run in a simple, non-preemptive, round-robin scheduling order. As you can imagine, writing CPU-intensive code can have negative repercussions on other threads running in the same process. In general, you should try to write "well-behaved" threads that voluntarily relinquish the CPU periodically and give other threads an opportunity to run. In particular, you should never write Java code that relies on time- sharing--this will practically guarantee that your program will give different results on different computer systems.
7
Sincronizzazione Balance = 15; if (Balance – 10 >= 0) Balance -= 10; Thread1Thread2Balance If( … )15 If( … )15 Balance -=105 -5 !!
8
Sincronizzazione/1 1.Uso di blocchi synchronized 2.Uso dei metodi wait() e notify() (appartengono alla classe Object) Noi vediamo synchronized
9
Sincronizzazione/2 E’ necessario che un solo thread alla volta possa eseguire il blocco di codice Ciò può essere dichiarato con la sintassi seguente: synchronized ((Integer) Balance) { if (Balance – 10 >= 0) Balance -= 10; }
10
Sincronizzazione/3 Il thread che esegue per primo l’istruzione synchronized acquisisce il controllo (lock) dell’oggetto Balance Il lock è rilasciato all’uscita del blocco Nessun altro thread può eseguire istruzioni del blocco senza aver prima acquisito il lock sull’oggetto
11
Sincronizzazione/4 Si possono dichiarare metodi synchronized (anche statici) class myClass { private int myVar; public synchronized void myMethod(int newVal) { myVar = newVal; }...... Solo un thread alla volta può modificare myVar (quello che ottiene il lock sull’oggetto di tipo myClass)
12
Thread Sincronizzati Thread separati devono considerare la condivisione di dati e lo stato di attività degli altri Threads. Thread A Thread B write read Occorre comunque sincronizzare threads che condividono una risorsa
13
Produttore/Consumatore PRODUCER CONSUMER i cubbyhole i cubbyhole.put(i) i cubbyhole.get() sleep(random) k synchronized Il consumatore non deve acedere il cubbyhole quando viene modificato dal produttore, e il produttore non deve modificarlo quando il consumatore sta accedendo get, put methods synchronized.
14
Skeleton public class CubbyHole { private int contents; private boolean available = false; public synchronized int get() {... } public synchronized void put(int value) {... } } public synchronized void put(int value) { // CubbyHole locked by the Producer.. // CubbyHole unlocked by the Producer } public synchronized int get() { // CubbyHole locked by the Consumer... // CubbyHole unlocked by the Consumer }
15
Il sistema associa un unico lucchetto ad ogni istanza di CubbyHole (compresa quella condivisa dal produttore e dal consumatore). Quando il controllo invoca un metodo sincronizzato, il thread che ha chiamato questo metodo blocca l’oggetto su cui il metodo è stato invocato. Gli altri threads non possono chiamare un metodo sincronizzato sullo stesso oggetto finchè l’oggetto non è rilasciato. L’acquisizione ed il rilascio di un lucchetto è realizzato automaticamente ed in modo atomico dal sistema runtime di Java. Questo evita corse critiche ell’implementazione dei threads e l’integrità dei dati. La sincronizzazione non conclude la questione. Due thread devono anche essere in grado di notificare reciprocamente l’avvenuto svolgimento di un compito. PRODUCER put i i
16
public synchronized int get() { if (available == true) { available = false; return contents; } public synchronized void put(int value) { if (available == false) { available = true; contents = value; } Cosa succede se il produttore non ha disposto alcun oggetto nel Cubbyhole e available non è true? get non fa nulla Se il produttore invoca put prima che il consumatore ottenga il valore, non si ha nessun valore nel Cubbyhole. WAIT & NOTIFYALL
17
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(); } private boolean available = false Il metodo wait rilascia il lock ottenuto dal consumatore sul CubbyHole e quindi attende la notifica del produttore Il produttore può ottenere il lock e qundi aggiornare il CubbyHole Quando il produttore dispone qualcosa nel CubbyHole, notifica il consumatore atraverso notifyAll Il consumatore esce dallo stato di wait, available è ora true, il loop termina ed il metodo get restituisce il valore nel Cubbyhole. Ilmetodo notifyAll risveglia tutti i threads in attesa sull’oggetto in questione. I threads notificati competono per il lock. Un thread otterrà l’oggetto, mentre gli altri torneranno in stato di attesa. La classe Object anche definisce un metodo notify, che risveglia arbitrariamente une dei thread in attesa sull’oggetto. wait
Presentazioni simili
© 2024 SlidePlayer.it Inc.
All rights reserved.