la classe Thread oppure è possibile implementare l'interfaccia Runnable.
Nel caso si decide di utilizzare la classe Thread per far si che il thread esegua quelle che si vuole bisogna fare l'override del metodo run(), un modo alternativo per implementare i threads è quello di creare una classe che implementa
l'interfaccia Runnable e definire quindi il metodo run(), poi si deve passare come parametro un'istanza di tale classe al costruttore della classe Thread.
In entrambi i modi di implementare i thread il corpo del thread stesso risiede nel metodo run().
LifeCycle
Come si può notare dalla figura i thread si possono trovare in quattro diversi stati
- Nuovo
- Eseguibile(o runnable)
- Bloccato
- Concluso
- Nuovo:il thread è in questo stato quando grazie all'operatore new si crea un nuovo thread per esempio new Thread(t) dove t è un oggetto di una classe che implementa l'interfaccia Runnable.
- Runnable:dopo aver chiamato il metodo start() il thread si trova nello stato eseguibile(o runnable), anche se effettivamente non sia detto che questo sia in esecuzione magari perchè il sistema operativo non l'abbia ancora schedulato. Quindi ci si deve ricordare che quando un thread è nello stato runnable non è detto che esso sia davvero in esecuzione.
- Bloccato:un thread si può trovare nello stato bloccato quando:
- Il thread è sospeso da una chiamata del metodo sleep()
- Il thread è bloccato nell'attesa di completamento di un richiesta di I/O
- Il thread tenta di ottenere l'accesso(lock) ad una risorsa condivisa detenuta da un altro thread
- Il thread attende che si verifichi una particolare condizione
Il thread sospeso ritorna nello stato runnable solo quando la condizione che l'ha portato nello stato bloccato cessa di esistere quindi:
- Quando i millisecondi indicati nella chiamata del metodo sleep() sono terminati
- Quando si conclude l'operazione di I/O richiesta
- Quando riesce ad ottenere il lock alla risorsa condivisa
- Quando la condizione che aspettava si è verifica
- Concluso:un thread può concludersi perchè il codice del metodo run() viene eseguito tutto e quindi il metodo stesso termina, oppure perchè un'eccezione non catturata termina il metodo run(). Per interrompere un thread si può utilizzare il metodo stop(), mentre per verificare se un thread è nello stato eseguibile o bloccato si può utilizzare il metodo isAlive() che ritorna il valore true se il thread è appunto eseguibile o bloccato, mentre ritorna il valore false se il thread non è ancora runnable o concluso.
Proprietà dei thread
- Priorità dei thread:Nel linguaggio Java ogni thread ha una priorità è possibile aumentare o diminuire questa priorità utilizzando il metodo setPriority(int newPriority), si può impostare la priorità con un valore compreso tra MIN_PRIORITY(definito come 1 nella class Thread) e MAX_PRIORITY(definito come 10 nella class Thread). Tuttavia si deve tener conto che la priorità dei thread è molto legata al sistema operativo, quindi la priorità viene mappata rispetto ai livelli di priorità del sistema operativo ospite, questi livelli possono essere diversi da quelli definiti dal linguaggio Java si dovrebbe evitare quindi di strutturare programmi che funzionano con la priorità dei thread.
- Thread demoni:un thread può essere trasformato in un demone chiamando il metodo setDaemon(true) un thread di questo tipo ha lo scopo di servire altri thread.
- Gruppi di thread:il linguaggio Java permette di classificare i thread di uno stesso programma in gruppi, ciò è possibile grazie alla classe ThreadGroup.
Esempio:
...
String nomeGrupp="pippo";
ThreadGroup g=new ThreadGroup(nomeGruppo);
Thread t=new Thread(g,"nomeThread");
...
public class ExampleThread extends Thread {
public ExampleThread(String name) {
super(name);
}
public void run() {
for (int i = 0; i < 100000; i++) {
System.out.println(this.getName()+" "+i+" volte");
}
}
public static void main(String[] args) {
ExampleThread t = new ExampleThread("ExampleThread");
t.start();
for (int i = 0;i<1000000;i++)
System.out.println("Main "+i+" volte");
}
}
Vediamo invece ora l'implementazione di Runnable
public class ExampleRunnableThread implements Runnable {
public void run() {
for (int i = 0; i < 100000; i++) {
System.out.println(Thread.currentThread().getName() + " " + i + " volte");
}
}
public static void main(String[] args) {
ExampleRunnableThread r = new ExampleRunnableThread();
Thread t=new Thread(r);
t.setName("ExampleRunnable thread");
t.start();
for (int i = 0;i<1000000;i++)
System.out.println("Main "+i+" volte");
}
}
I due esempi illustrati dovrebbero mostrarvi come la CPU per un certo periodo esegue il thread main e per un certo intervallo l'altro thread con un'alternanza dei due thread.
Nessun commento:
Posta un commento