Thread Java

In questa lezione tratteremo la creazione di Thread Java:

Definizione

Un thread (detto anche Light-weight process) è un sottoprocesso, ovvero un unità granulare in cui un processo può essere suddiviso. i Threads possono essere eseguiti in modo concorrente, ovvero concorrono nell’utilizzo di una particolare risorsa come la CPU.

Le specifiche ufficiali della Java Virtual Machine stabiliscono che una VM gestisca i threads secondo uno scheduling preemptive (fixed-priority scheduling).

Creazione Thread

Ci sono due modi per creare un thread nel linguaggio Java:

Estendere classe Thread

public class Counter extends Thread{
    public void run(){
        setName("Thread Counter");
        System.out.println(Thread.currentThread().getName());
        for(int i=0;i<7;i++){
            System.out.println((i+1)+" ");
        }
    }
}

estendiamo la classe Thread e quindi ereditiamo tutti i suoi metodi come setName()che ci permette di impostare un nome al Thread. Nel metodo run()indichiamo il lavoro da svolgere, nel nostro caso un conteggio da 1 a 7.

Dopodiché testiamo il nostro Thread con il seguente codice:

public class TestCounter {
    public static void main(String[] args) {
        System.out.println("Primo Thread:    ----> "+Thread.currentThread().getName());
        Counter counter=new Counter();
        counter.start();
    }
}

NOTA: Il programma non invoca run() direttamente; se si vuole avviare un Thread counter, si esegue il metodo counter.start() e la JVM si occuperà di chiamare counter.run().

Notiamo anche che lo stesso main è il primo thread!

Due Threads
public class Counter2 extends Thread{
    public Counter2(String name){
        super(name);
    }
    public void run(){
        for(int i=0;i<7;i++){
            System.out.println((i+1)+" Sono: "+Thread.currentThread().getName());
        }
    }
}

utilizzando la parola chiave super()utilizziamo il costruttore Thread(String name) della sopra classe Thread e quindi passiamo una stringa nel momento di creare un oggetto che rappresenta il nome del thread.

Infine, testiamo la classe con il seguente codice

public class TestCounter2 {
    public static void main(String[] args) {
        Counter2 c1=new Counter2("PuffoGino");
        Counter2 c2=new Counter2("Nino");
        c1.start();
        c2.start();
    }
}

NOTA: ogni esecuzione del programma, come era presumibile dalla definizione iniziale, è aleatoria e la priorità dei Thread cambia con essa

output di un'esecuzione dei due thread Counter2
output di un’esecuzione dei due thread Counter2

In ambedue gli esempi si sono invocati i metodi statici currentThread() che restituisce il Thread corrente in esecuzione e getName()ne restituisce il nome, che nel primo esempio abbiamo impostato con il metodo setName() mentre nel secondo esempio tramite il costruttore

Implementare interfaccia Runnable

public class Piano implements Runnable{
    String note;
    int numberOfTimes;
    public Piano(String note, int numberOfTimes){
        this.note=note;
        this.numberOfTimes=numberOfTimes;
    }
    @Override
    public void run() {
        for(int i=0;i<numberOfTimes;i++){
            System.out.println((i+1)+note+" ");
        }
    }
}

Implementiamo l’interfaccia Runnable che ci mette a disposizione il suo metodo astratto run()dove specificheremo l’algoritmo che effettuerà il thread. Il nostro Thread rappresenta un Pianoforte che suona la nota un certo numero di volte (parametri del costruttore)

E’ difatti preferibile utilizzare questa seconda modalità in quanto

  • non è possibile ereditare da altre classi (anche qualora ciò fosse reso necessario dal progetto in corso di realizzazione)
  • Si ereditano tutti i metodi di Thread, che non è sempre necessario

Adesso, testiamo la classe

public class TestPiano {
    public static void main(String[] args) {
        // metodo 1
        Runnable run_p1=new Piano("DO",5);
        Thread p1=new Thread(run_p1);
        p1.start();
        // metodo 2
        Thread p2=new Thread(new Piano("SOL",5));
        p2.start();
        // metodo 3
        new Thread(new Piano("Mib",5)).start();
    }
}

In questo test creiamo in tre differenti modi tre thread:

  • nel metodo 1 creiamo un nuovo oggetto Piano che implementa Runnable e lo passiamo al costruttore di Thread -> Thread(Runnable target)
  • nel metodo 2 creiamo un nuovo Thread senza creare un reference di Piano con la dichiarazione implicita grazie alla parola chiave new
  • nel metodo 3 utilizziamo solo dichiarazioni implicite senza reference degli oggetti

Pubblicato da Carlo Contardi

Carlo Contardi, docente di informatica e sviluppatore Full Stack, condivide la sua passione per la programmazione e l’informatica attraverso il suo blog Space Coding. Offre preziosi consigli e soluzioni pratiche a chi vuole imparare a programmare o migliorare le proprie abilità. 🚀👨‍💻

Translate »