Skip to content

Instantly share code, notes, and snippets.

@salvatorecapolupo
Created March 3, 2026 06:38
Show Gist options
  • Select an option

  • Save salvatorecapolupo/edb0cc327ac4de4a0812535c536ed285 to your computer and use it in GitHub Desktop.

Select an option

Save salvatorecapolupo/edb0cc327ac4de4a0812535c536ed285 to your computer and use it in GitHub Desktop.
Thread in Java - Fonte: edutecnica.it

PARTE 1: Le Basi (Teoria)

1. Estendere la classe Thread

Il modo più classico (anche se rigido) per creare un processo parallelo.

class MioThread extends Thread {
    public void run() {
        System.out.println("1. Ciao dal thread: " + getName());
    }
}

public class Base1 {
    public static void main(String[] args) {
        new MioThread().start(); // Avvia il thread, non chiamare run()!
    }
}

2. Implementare Runnable

L'approccio preferito in Java, perché lascia la classe libera di estendere altre cose.

public class Base2 {
    public static void main(String[] args) {
        Runnable compito = () -> System.out.println("2. Lavoro tramite Runnable");
        new Thread(compito).start();
    }
}

3. Priorità dei Thread

Possiamo "suggerire" alla JVM chi è più importante (da 1 a 10). La JVM ha comunque l'ultima parola.

public class Base3 {
    public static void main(String[] args) {
        Thread t1 = new Thread(() -> System.out.println("Thread Basso"));
        Thread t2 = new Thread(() -> System.out.println("Thread Alto"));
        
        t1.setPriority(Thread.MIN_PRIORITY); // 1
        t2.setPriority(Thread.MAX_PRIORITY); // 10
        
        t1.start(); t2.start();
    }
}

4. Cedere il passo (yield)

Un thread dice: "Ho fatto abbastanza per ora, cedo volentieri la CPU ad altri thread di pari priorità".

public class Base4 {
    public static void main(String[] args) {
        new Thread(() -> {
            System.out.println("Inizio lavoro lungo...");
            Thread.yield(); // Metto in pausa me stesso per far passare altri
            System.out.println("Riprendo e finisco!");
        }).start();
    }
}

5. Sospensione programmata (sleep)

Il thread si addormenta per un tempo millesimale esatto.

public class Base5 {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("Inizio attesa...");
        Thread.sleep(2000); // Il main dorme per 2 secondi
        System.out.println("Sono passati 2 secondi!");
    }
}

6. Sincronizzazione base (join)

Il thread principale aspetta che un altro abbia finito prima di proseguire.

public class Base6 {
    public static void main(String[] args) throws InterruptedException {
        Thread operaio = new Thread(() -> System.out.println("Operaio: Finito!"));
        operaio.start();
        
        operaio.join(); // Il Main aspetta qui
        System.out.println("Main: L'operaio ha finito, chiudo il cantiere.");
    }
}

PARTE 2: Gli Esercizi Risolti (Da threadx.htm)

Ecco i 4 esercizi finali, ottimizzati per essere leggibili e focalizzati sull'obiettivo.

7. Esercizio 1: I due contatori sfasati

Obiettivo: Due thread, uno conta da 1 a 10, l'altro da 100 a 50 su colonne diverse (usando i tabulati \t).

public class Ex1_Colonne {
    public static void main(String[] args) {
        // Colonna Sinistra (1 -> 10)
        new Thread(() -> {
            for(int i=1; i<=10; i++) System.out.println(i + "\t");
        }).start();

        // Colonna Destra (100 -> 50)
        new Thread(() -> {
            for(int i=100; i>=50; i--) System.out.println("\t\t" + i);
        }).start();
    }
}

8. Esercizio 2: La Pizzeria (Attesa fissa)

Obiettivo: Simulare un cliente che ordina e aspetta 5 secondi la preparazione della pizza.

public class Ex2_Pizzeria {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("Cliente: Ordino la margherita e aspetto...");
        
        Thread pizzaiolo = new Thread(() -> {
            try {
                System.out.println("Pizzaiolo: Preparazione in corso (5s)...");
                Thread.sleep(5000); // Cottura
                System.out.println("Pizzaiolo: Pizza pronta!");
            } catch (InterruptedException e) {}
        });
        
        pizzaiolo.start();
        pizzaiolo.join(); // Il cliente aspetta che il pizzaiolo finisca
        
        System.out.println("Cliente: Grazie, finalmente mangio!");
    }
}

9. Esercizio 3: Produttore/Consumatori con Buffer unitario e Filtro

Obiettivo: Buffer da 1 posto. Produttore genera 1-10. Consumatore A mangia solo 1-5, Consumatore B mangia solo 6-10.

public class Ex3_ProdCons {
    static class Buffer {
        int dato = 0;
        boolean pieno = false;

        // Metodo per il PRODUTTORE
        synchronized void produci(int n) throws InterruptedException {
            while (pieno) wait(); // Se è pieno, aspetto
            dato = n;
            pieno = true;
            System.out.println("Prodotto: " + n);
            notifyAll(); // Avviso i consumatori
        }

        // Metodo per i CONSUMATORI (A accetta 1-5, B accetta 6-10)
        synchronized void consuma(boolean vuoleBassi) throws InterruptedException {
            // Condizione di attesa: o è vuoto, o c'è un numero che non mi piace
            while (!pieno || (vuoleBassi && dato > 5) || (!vuoleBassi && dato <= 5)) {
                wait(); 
            }
            System.out.println((vuoleBassi ? "Cons. Basso" : "Cons. Alto") + " mangia: " + dato);
            pieno = false;
            notifyAll(); // Avviso il produttore che ho liberato il posto
        }
    }

    public static void main(String[] args) {
        Buffer b = new Buffer();

        new Thread(() -> { // Produttore
            try { for(int i=1; i<=10; i++) b.produci((int)(Math.random()*10)+1); } catch(Exception e){}
        }).start();

        new Thread(() -> { // Consumatore Basso (1-5)
            try { while(true) b.consuma(true); } catch(Exception e){}
        }).start();

        new Thread(() -> { // Consumatore Alto (6-10)
            try { while(true) b.consuma(false); } catch(Exception e){}
        }).start();
    }
}

10. Esercizio 4: Il Parcheggio (Timeout di Wait)

Obiettivo: 10 auto, 5 posti. Attesa massima in coda 20 secondi. Sosta massima 10 secondi. Segnali di wait e notify.

public class Ex4_Parcheggio {
    static class Parcheggio {
        int postiLiberi = 5;

        synchronized boolean entra() throws InterruptedException {
            long inizioAttesa = System.currentTimeMillis();
            
            // Finché non ci sono posti, aspetto...
            while (postiLiberi == 0) {
                long tempoPassato = System.currentTimeMillis() - inizioAttesa;
                if (tempoPassato >= 20000) return false; // Scaduti i 20 sec, me ne vado!
                
                // Aspetto il tempo che mi rimane per arrivare a 20 sec
                wait(20000 - tempoPassato); 
            }
            
            postiLiberi--; // Posto preso
            return true;
        }

        synchronized void esci() {
            postiLiberi++; // Libero il posto
            notifyAll();   // Avviso le auto in coda!
        }
    }

    public static void main(String[] args) {
        Parcheggio p = new Parcheggio();

        for (int i = 1; i <= 10; i++) {
            Thread auto = new Thread(() -> {
                String nome = Thread.currentThread().getName();
                try {
                    System.out.println(nome + " cerca parcheggio...");
                    if (p.entra()) {
                        System.out.println(nome + " HA PARCHEGGIATO.");
                        Thread.sleep((long)(Math.random() * 10000)); // Sosta fino a 10 sec
                        p.esci();
                        System.out.println(nome + " è uscita.");
                    } else {
                        System.out.println(nome + " RINUNCIA: attesa oltre 20s.");
                    }
                } catch (InterruptedException e) {}
            });
            auto.setName("Auto-" + i);
            auto.start();
        }
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment