I Thread in Java – Lezione 39 di Java Avanzato

I thread sono flussi di esecuzione all’interno di un processo. Java è uno dei pochi linguaggi di programmazione che possiede un supporto nativo ai thread, ovvero che non bisogna importare librerie per rendere un programma multithreading. Per multithreading si intende la capacità dei programmi di eseguire, al loro interno, più task (thread) contemporaneamente.

Ogni programma Java possiede almeno un thread di esecuzione, detto thread principale. Si tratta del thread creato con l’esecuzione del main, da esso si generano gli altri thread. I thread appartenenti allo stesso processo condividono la memoria e i file aperti, tranne il program counter e lo stack. Questi elementi non condivisi rappresentano le risorse che consentono ad un thread di avere un flusso di esecuzione indipendente da gli altri thread.

Creazione di un thread: classe Thread e interfaccia Runnable

Esistono due modi per creare un thread, il primo metodo prevede di estendere la classe Thread. I passi da seguire per creare un thread in Java con questo metodo sono:

  1. Creare una classe e fargli estendere la classe Thread;
  2. Effettuare l’overriding del metodo run, la cui intestazione in Thread è:
      public void run();
  3. Istanziare la classe appena creata;
  4. Chiamare il metodo start dell’oggetto creato che in Thread che ha la seguente forma:
      public void start(){...}

Il metodo run viene chiamato playsorder perchè si tratta un metodo fittizio che nel nostro caso conterrà il corpo del nuovo thread. Il metodo run rappresenta l’entry point del thread, è come se fosse la funzione iniziale (main) del thread.
La classe Thread ha il corpo del metodo run vuoto, le sue sottoclassi forniranno il corpo specifico per ogni thread.

  public class MyThread extends Thread {
    @Override
    public void run() {
      System.out.println("Ciao, sono un nuovo thread!");
    }
  }

Per poter far partire il thread appena creato, dobbiamo istanziare la classe MyThread e farlo partire con il metodo start:

  MyThread t = new MyThread();
  t.start();

Questo metodo per la creazione di un thread estendendo la classe Thread, non può estendere ulteriori classi.

Un metodo alternativo per creare in Java un thread senza estendere la classe Thread è di implementare l’interfaccia Runnable:

L'interfaccia Runnable

L’interfaccia Runnable è così definita:

  public interface Runnable {
    public void run();
  }

I passi per creare un thread implementando l’interfaccia Runnable sono i seguenti:

  1. Creare una classe che estende Runnable;
  2. Istanziare la classe creata;
  3. Passare l’oggetto Runnable ad un nuovo oggetto Thread;
  4. Invocare il metodo start.

La creazione di un thread con l’utilizzo dell’interfaccia Runnable è consigliato perchè sottolinea il fatto che la classe creata è staccata dal thread vero e proprio. Spesso Runnable viene istanziata come una classe anonima.

L’interfaccia contiene solo un metodo run del tutto analogo a quello della classe Thread. Tale metodo sarà l’entry point per il nuovo thread di esecuzione. Per creare il thread, utilizziamo il costruttore della classe Thread e gli passiamo come argomento un oggetto della nostra classe che implementa Runnable:

  public Thread(Runnable r)

E’ possibile utilizzare lo stesso oggetto Runnable per creare più thread, tutti i thread eseguiranno lo stesso metodo run.

Vediamo un esempio di creazione di un thread con l’utilizzo di un’interfaccia Runnable:

  class MyRunnable implements Runnable {
    @Override
    public void run() {
      for(int i=0; i<100; i++)
        System.out.println("CICLO " + i);
    }
  }

  public class Test {
    public static void main(String args[]) {
      MyRunnable e = new MyRunnable();
      Thread t = new Thread(e);
      t.start();
    }
  }

La classe MyClass stampa i numeri da 0 a 99 preceduti dalla parola “Ciclo:”. Per creare il thread è necessario istanziare la classe MyRunnable, dopodiché creare un nuovo Thread utilizzando il costruttore della classe Thread che accetta un’interfaccia Runnable come argomento. Runnable può essere utilizzata anche come classe anonima:

  public class Test {
    public static void main(String args[]) {
      Thread t = new Thread(new Runnable(){
        @Override
        public void run() {
          for(int i=0; i<100; i++) {
            System.out.println("Ciclo: " + i);
          }
        }
      });
      t.start();
    }
  }

Interfacce Callable e Future

L’interfaccia Callable è simile a Runnable, la principale differenza è che preve di restituire un valore:

  public interface Callable<V> {
    V call() throws Exception;
  }

L’interfaccia Future può essere usata per lanciare una computazione (asincrona) in modo da ottenere successivamente il risultato:

  public interface Future<V> {
    V get() throws InterruptedException, ExecutionException;
    V get(long timeout, TimeUnit unit) throws InterruptedException,
                                     ExecutionException, TimeoutException;
    void cancel(boolean mayInterrupt);
    boolean isCancelled();
    boolean isDone();
  }

Indice Lezione PrecedenteLezione Successiva

Pubblicato in Guide, Java, Programmazione Taggato con: , , , ,

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

*