Il Thread Principale in Java

Concetti Chiave
  • Il thread principale in Java è il thread che viene eseguito quando un programma Java inizia.
  • Si può ottenere un riferimento al thread principale usando il metodo Thread.currentThread().
  • Si può cambiare il nome del thread principale usando il metodo setName().
  • Il metodo sleep() permette di sospendere l'esecuzione del thread per un periodo specificato.

Il Thread Principale

Quando un programma Java si avvia, un thread inizia immediatamente l'esecuzione.

Questo è solitamente chiamato il thread principale (Main Thread) del programma, perché è quello che viene eseguito quando il programma inizia la propria esecuzione.

Il thread principale è importante per due ragioni:

  • È il thread dal quale altri thread figli (children) verranno generati.
  • Spesso, deve essere l'ultimo thread a terminare l'esecuzione perché esegue varie azioni di chiusura.

Anche se il thread principale viene creato automaticamente quando un programma viene avviato, può essere controllato attraverso un oggetto Thread.

Per fare ciò, bisogna ottenere un riferimento ad esso chiamando il metodo currentThread(), che è un membro public static di Thread.

La sua forma generale è mostrata qui:

static Thread currentThread()

Questo metodo restituisce un riferimento al thread nel quale viene chiamato. Una volta che si ha un riferimento al thread principale, lo si può controllare proprio come qualsiasi altro thread.

Iniziamo osservando il seguente esempio:

// Controllare il thread principale.
class DemoThreadCorrente {
    public static void main(String[] args) {
        // ottiene un riferimento al thread corrente
        Thread t = Thread.currentThread();

        System.out.println("Thread corrente: " + t);

        // cambia il nome del thread
        t.setName("Il Mio Thread");

        System.out.println("Dopo il cambio di nome: " + t);

        try {
            // Effettua un conto alla rovescia da 5 a 1
            // con una pausa di 1 secondo tra ogni numero
            System.out.println("Inizio conto alla rovescia:");
            for(int n = 5; n > 0; n--) {
                System.out.println(n);
                Thread.sleep(1000);
            }
        } catch (InterruptedException e) {
            // Questa eccezione viene lanciata se il thread viene interrotto
            // usando CTRL+C o un altro metodo
            System.out.println("Thread principale interrotto");
        }
    }
}

In questo programma, un riferimento al thread corrente (il thread principale, in questo caso) viene ottenuto chiamando currentThread(), e questo riferimento viene memorizzato nella variabile locale t.

Successivamente, il programma visualizza informazioni sul thread. Il programma quindi chiama setName() per cambiare il nome interno del thread. Le informazioni sul thread vengono poi visualizzate nuovamente.

Successivamente, un ciclo conta alla rovescia da cinque, mettendo in pausa un secondo tra ogni riga. La pausa viene realizzata dal metodo sleep(). L'argomento di sleep() specifica il periodo di ritardo in millisecondi.

Si noti il blocco try/catch attorno a questo ciclo. Il metodo sleep() in Thread potrebbe lanciare un eccezione di tipo InterruptedException. Questo piò accadere quando, ad esempio, usiamo la combinazione di tasti CTRL+C sulla console.

Questo esempio stampa semplicemente un messaggio se viene interrotto. In un programma reale, bisognerebbe gestire questo evento diversamente.

Ecco un possibile output generato da questo programma:

Thread corrente: Thread[main,5,main]
Dopo il cambio di nome: Thread[Il Mio Thread,5,main]
5
4
3
2
1

Si noti l'output prodotto quando t viene usato come argomento per println(). Questo visualizza, in ordine: il nome del thread, la sua priorità, e il nome del suo gruppo.

Per impostazione predefinita, il nome del thread principale è main. La sua priorità è 5, che è il valore predefinito, e main è anche il nome del gruppo di thread al quale questo thread appartiene.

Un gruppo di thread è una struttura dati che controlla lo stato di una collezione di thread nel loro insieme. Dopo che il nome del thread viene cambiato, t viene visualizzato di nuovo. Questa volta, viene visualizzato il nuovo nome del thread.

Esaminiamo più da vicino i metodi definiti da Thread che vengono usati nel programma. Il metodo sleep() fa sì che il thread dal quale viene chiamato sospenda l'esecuzione per il periodo specificato di millisecondi. La sua forma generale è mostrata qui:

static void sleep(long millisecondi) throws InterruptedException

Il numero di millisecondi da sospendere è specificato in millisecondi. Questo metodo può lanciare un'InterruptedException.

Il metodo sleep() ha una seconda forma, mostrata di seguito, che permette di specificare il periodo in termini di millisecondi e nanosecondi:

static void sleep(long millisecondi, int nanosecondi) throws InterruptedException

Questa seconda forma è utile solo in ambienti che permettono periodi di temporizzazione brevi come i nanosecondi.

Come mostra il programma precedente, si può impostare il nome di un thread usando setName(). Si può ottenere il nome di un thread chiamando getName() (ma si noti che questo non è mostrato nel programma).

Questi metodi sono membri della classe Thread e sono dichiarati così:

final void setName(String nomeThread)
final String getName( )

Qui, nomeThread specifica il nome del thread.