Multithreading in Java
Fondamenti di Sistemi Informativi
2014 - 2015
Multithreading
●
●
●
La programmazione concorrente consente di eseguire più
processi o thread nello stesso momento. Nel secondo caso si
parla di Multithreading
Un thread è un sottoprocesso computazionale. I thread sono più
leggeri dei processi e sfruttano una comunicazione a memoria
condivisa
Diversi thread contenuti nello stesso processo condividono
alcune risorse (memoria e file aperti), mentre processi differenti
non condividono le loro risorse
Sistemi multiprocessore e
multithreaded
Un sistema multithreaded ha un singolo processore e il
multithreading è generalmente implementato alternando l'esecuzione
dei diversi thread in modo abbastanza frequente da dare all'utente la
percezione che le attività siano eseguite allo stesso tempo.
Multithreaded process
http://en.wikipedia.org/wiki/File:Multithreaded_process.svg
Mentre, in un sistema multiprocessore o multi-core, i thread possono
essere eseguiti realmente in maniera concorrente, sfruttando ogni
processore o core per eseguire diversi thread contemporaneamente.
Alcuni Usi del multithreading
●
●
Consente di velocizzare l'esecuzione dei programmi tramite
parallelizzazione per sfruttare i moderni processori multi-core,
condivisione di memoria e comunicazione fra thread più
efficiente
Consente di rendere più efficienti i programmi evitando che
il flusso di esecuzione resti bloccato fino al termine di una
attività, evento o rilascio di una risorsa.
Per esempio è usato per realizzare applicazioni interattive
implementando funzioni asincrone rispetto al normale flusso di
esecuzione di un programma e web server che devono
connettersi con più client contemporaneamente
Multi-threading in Java
I programmi Java possono essere multi-threaded. Le
piattaforme Java implementano il timeslicing, che consente a
più thread di condivedere un processore In base ai valori di
priority
Esistono due metodi per implementare il multi-threading
●
estendendo la classe Thread
●
implementando l'interfaccia Runnable
Il primo metodo è più semplice del secondo, ma meno
flessibile. Il secondo permette di definire Thread che estendono
altre classi (in Java si può estendere solo una classe!) e di
utilizzare meccanismi più avanzati per la schedulazione di
Thread
Metodo “thread”
●
●
●
●
Il metodo più importante per la classe Thread è run(), che va
sovrascritto per farlo comportare esattamente come vogliamo
run( ) contiente il codice che sarà eseguito “simultaneamente”
con gli altri thread in un programma
il metodo start( ) nella classe Thread esegue delle operazioni
di inizializzazione per il thread e poi chiama run( )
ATTENZIONE: è necessario sovrascrivere run() ma invocare
start() che lancia il thread e ritorna immediatamente. Invocare
direttamente il metodo run() blocca l'esecuzione del
programma finché non termina run()
Esempio metodo “thread”
public class HelloThread extends Thread {
public void run() {
System.out.println("Hello from a thread!");
}
public static void main(String args[]) {
HelloThread hello = new HelloThread();
hello.start();
}
}
Metodo “runnable”
●
●
●
La nuova classe deve implementare l'interfaccia Runnable e
può eventualmente estendere un'altra classe.
Il metodo run() va implementato nello stesso modo.
Per poter eseguire un oggetto Runnable è necessario istanziare
la classe Thread e passare tale oggetto come parametro al
costruttore
Esempio metodo “runnable”
public class HelloRunnable implements Runnable {
public void run() {
System.out.println("Hello from a thread!");
}
public static void main(String args[]) {
HelloRunnable hello = new HelloRunnable();
Thread t = new Thread( hello);
t.start();
}
}
Altri metodi della classe Thread
●
getName / getPriority restituisce nome/priorità del thread
●
setName / setPriority
●
sleep sospende l'esecuzione del thread per m millisecondi;
●
●
modifica nome/priorità del thread
yield sospende l'esecuzione del thread corrente consentendo
l'esecuzione di altri thread pronti e a uguale priorità
join
attende la terminazione del thread per eseguire altri thread
Synchronization
●
●
●
La comunicazione fra thread avviene principalmente mediante condivisione
di memoria, quindi accedendo agli stessi oggetti. È una forma di
comunicazione estremamente efficiente, ma può causare problemi, fra cui:
–
Thread Interference, modifica dello stesso dato simultaneamente
–
Memory Consistency Errors, differenti thread hanno differenti
viste dello stesso dato
La sincronizzazione permette di prevenire tali problemi
È possibile sincronizzare un metodo (Synchronized Methods) o blocchi di
istruzioni (Synchronized Statements). Il secondo metodo consente di evitare
di sincronizzare l'intero metodo e di specificare più precisamente quali
oggetti sincronizzare migliorando la concorrenza con una sincronizzazione
fine-grained (granularità più fine)
Synchronized Methods
public class SynchronizedCounter {
private int c = 0;
public synchronized void increment() {
c++;
}
public synchronized void decrement() {
c--;
}
public synchronized int value() {
return c;
}
}
Fine-grained Synchronized Statements
public class MsLunch {
long c = 0;
Object lock = new Object();
public void inc() {
// qui potrebbero esserci altre istruzioni
synchronized(lock1) {
c++;
}
// anche qui potrebbero esserci altre istruzioni
}
}
Sincronizzazione: uso del Monitor
●
●
●
●
●
Il monitor permette di aggiungere una specifica della sincronizzazione fra i
threads per mezzo dell’invocazione dei seguenti metodi:
wait() rilascia il lock sull'oggetto e sospende il thread che lo invoca in attesa
di una notifica.
notifyAll() risveglia tutti i thread sospesi sull'oggetto in attesa di notifica. I
thread risvegliati competono per acquisire il lock sull'oggetto.
notify() risveglia un thread scelto casualmente tra quelli sospesi sull'oggetto
in attesa di notifica. Il thread risvegliato compete per acquisire il lock
sull'oggetto.
Tali metodi devono essere invocati dall'interno di un metodo o blocco
sincronizzato
Alcuni link utili
●
●
Java tutorial
http://docs.oracle.com/javase/tutorial/essential/concurrency/index.html
Multi-threaded Client/Server Applications
http://www.ase.md/~aursu/ClientServerThreads.html