Una delle principali applicazioni dei thread è quella di permettere di organizzare l’esecuzione di lavori con attività in foreground e in background: per esempio, mentre un thread gestisce l’I/O con l’utente, altri thread eseguono operazioni sequenziali di calcolo in background, nei fogli elettronici vengono utilizzati per le procedure di ricalcolo automatico, nei fogli word per effettuare la reimpaginazione oppure il controllo automatico del documento, …
Utilizzo dei thread
Un altro importante utilizzo dei thread è quello di implementarli per eseguire attività asincrone, come per esempio le operazioni di garbage collection nella gestione della RAM oppure nelle procedure di salvataggio automatico dati (backup schedulati)
Threads in Java
Esistono tre possibilità diverse per definire un thread in Java1. creare un main;2. creare una sottoclasse della classe Thread;3. implementare l’interfaccia Runnable
Il linguaggio Java mette a disposizione dell’utente classi che implementano i thread in forma primitiva già dalla sua definizione
La prima modalità thread è implicita in un programma Java in quanto ognuno di essi contiene almeno un singolo thread, corrispondente all’esecuzione del metodo main() sulla JVMLa seconda modalità consiste nel creare i thread come oggetti di sottoclassi della classe ThreadLa terza modalità consiste invece nell’utilizzo dell’interfaccia Runnable, la quale risulta avere maggiore flessibilità rispetto al caso precedente
Java mette a disposizione la classe Thread fornita dal package java.lang. Essa è fondamentale per la gestione dei thread poiché in essa sono definiti i metodi per avviare, fermare, sospendere, riattivare ed eseguire tutte le procedure dei thread.
La prima modalità di creazione di thread in Java è ottenuta ereditando da tale classe una sottoclasse che utilizzi il metodo run () con la segnatura
public void run(void)
Il metodo run definisce l’insieme di istruzioni Java che ogni thread “creato come oggetto di quella classe” esegue concorrentemente con altri thread (nella classe Thread l’implementazione del suo metodo è vuota, pertanto in ogni sottoclasse derivata deve essere ridefinito con le istruzioni che costituiscono il corpo del thread, ovvero tutte le istruzioni che lo schedulatore deve eseguire quando il thread viene attivato)
Un programma che utilizza il thread si implementa quindi così:• si dichiara una classe principale all’interno della quale si specifica che in parallelo ad essa andrà in esecuzione un thread• si definisce il thread, a cui vengono attribuite le operazioni cosiddette leggere da svolgere
Per l’esecuzione di un thread si deve pertanto scrivere una classe di prova che ne definisca un’istanza e ne avvii l’esecuzione
In questo caso si definisce l’oggetto containani (che sarà il thread) nella classe di prova Provanani e si attiva il thread con il metodo start(): esso manda in esecuzione il metodo run() definito all’interno del thread
run nel thread
Come visto, è necessario ereditare dalla classe Thread una sottoclasse che utilizzi il metodo run(), in cui questo metodo definisce l’insieme di istruzioni Java che ogni Thread eseguirà
Parte del programma che svolge le operazioni: thread
Il metodo start() nella classe di prova invoca il metodo run(), che non può essere chiamato direttamente
La creazione di un oggetto thread non determina la sua esecuzione: il thread è ancora in stato di attesa
Esempio threadIn questo modo si sono creati due thread concorrenti:• il thread principale (associato al main);• il thread thr creato dinamicamente al precedente, in cui l’esecuzione dell’istruzione thr.start() lancia in concorrenza l’esecuzione del metodo run() del nuovo thread
thread
main
Per esempio, l’esecuzione seguente senza richiedere in out il nome del thread:
Un’esecuzione del thread produce sullo schermo il seguente output:
Si può osservare che ad ogni thread viene associato in modo automatico un nome: il primo thread ha nome main mentre a quelli successivi viene assegnato di default un nome con indice progressivo (come Thread-0)
Procedendo ad una inizializzazione del thread è possibile cambiarne il nome, come nel caso
In modo analogo, per il corpo del thread:
Il thread appena creato continua la sua evoluzione finché non è completata la sua esecuzione; quindi termina in modo spontaneo
In altri casi può risultare necessario fermare l’evoluzione del thread (tramite un altro thread) attraverso il metodo stop()
thr.stop():
main (classe di prova): viene modificata in modo da creare le due istanza con nomi diversi, thr2 e thr
thread uno: esegue una certa operazione
thread due: esegue un’operazione diversaoutput
Esempio due thread in esecuzione
In questo esempio viene inserito un costruttore per assegnare il nome al thread
main (classe di prova): viene modificata in modo da creare le due istanze con nomi diversi
thread con assegnazione nome mediante costruttore
Esempio due thread in esecuzione
Due esecuzioni producono sullo schermo il seguente output:
Si osserva come gli effetti della schedulazione producano risultati diversi
Top Related