Il problema
Non si tratta di un problema singolo ma piuttosto di una categoria di problemi: quelli in cui non è possibile eseguire una sola operazione alla volta. Le situazioni in cui si può presentare questa esigenza sopno molte, ad esempio:
- voglio portare a termine un lavoro più velocemente
- devo fare una elaborazione impegnativa ma non voglio bloccare l'interfaccia grafica
- devo tener d'occhio una situazione mentre faccio altro
Questi casi sono molto diversi tra loro e fanno sorgere problemi diversi: ad esempio se voglio elaborare un calcolo più velocemente potrei voler divedere il problema da risolvere in più parti (cosa non affatto ovvia da fare in tutti i casi) oppure due thread diversi potrebbero andare a modificare contemporaneamente la stessa struttura dati (ad esempio un vettore) portandola in uno stato inconsistente (diciamo insensato per capirci).
Fortunatamente Java prevede l'uso dei thread fin dalla sua versione iniziale e per questo
ci mette a disposizione diversi oggetti che ci semplificano molto la vita. I due principali che
possiamo usare per creare un nuovo thread sono appunto
java.lang.Thread
e java.lang.Runnable,
il secondo è più flessibile ma... il primo è più facile da usare!
Utilizzare la classe Thread
non è complicato: basta estendere la classe e
implementarne il metodo run()
, questo metodo è quello che verrà chiamato
quando si avvia il thread e che una volta terminato fa passare il thread stesso
nello stato di "died" (sarebbe a dire "terminato").
public class Esecutore extends Thread { @Override public void run(){ // codice da eseguire nel thread } }
Per quanto riguarda il problema dell'accesso concorrente alle strutture dati mensionato sopra la libreria di Java esplicita chiaramente se un oggetto è utilizzabile senza problemi e senza fare ulteriori controlli da due thread diversi: prendiamo per esempio il caso delle liste ad espansione dinamica. java.util.Vector è definito "thread-safe" (e quindi utilizzabile tranquillamente e in contemporanea da due thread diversi, magari con qualche problema sulle prestazioni) mentre java.util.ArrayList fa lo stesso lavoro ma non è thread-safe (ragionevolmente dovendo fare meno controlli è più veloce).