🚀 Nuova versione beta disponibile! Feedback o problemi? Contattaci

Esercizi Multithreading e Concorrenza in Java

Codegrind Team•Jul 12 2024

Ecco degli esercizi con soluzione per praticare l’uso del multithreading e della concorrenza in Java.

Esercizio 1: Creazione di un Thread

Creare e avviare un thread estendendo la classe `Thread`.
public class ThreadEsteso extends Thread {
    public void run() {
        System.out.println("Esecuzione del thread: " + Thread.currentThread().getName());
    }

    public static void main(String[] args) {
        ThreadEsteso thread = new ThreadEsteso();
        thread.start();
    }
}

Esercizio 2: Implementazione di Runnable

Creare e avviare un thread implementando l'interfaccia `Runnable`.
public class ThreadRunnable implements Runnable {
    public void run() {
        System.out.println("Esecuzione del thread: " + Thread.currentThread().getName());
    }

    public static void main(String[] args) {
        Thread thread = new Thread(new ThreadRunnable());
        thread.start();
    }
}

Esercizio 3: Sincronizzazione di un Blocco di Codice

Utilizzare la parola chiave `synchronized` per sincronizzare un metodo in una classe che implementa `Runnable`.
public class Sincronizzazione implements Runnable {
    private int contatore = 0;

    public synchronized void incrementa() {
        contatore++;
        System.out.println("Contatore: " + contatore);
    }

    public void run() {
        for (int i = 0; i < 5; i++) {
            incrementa();
        }
    }

    public static void main(String[] args) {
        Sincronizzazione obj = new Sincronizzazione();
        Thread t1 = new Thread(obj);
        Thread t2 = new Thread(obj);
        t1.start();
        t2.start();
    }
}

Esercizio 4: Uso di Callable e Future

Creare un task utilizzando `Callable` e recuperare il risultato utilizzando `Future`.
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class CallableEsempio {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Callable<Integer> task = () -> {
            Thread.sleep(1000);
            return 123;
        };

        Future<Integer> future = executor.submit(task);

        try {
            Integer result = future.get();
            System.out.println("Risultato: " + result);
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        } finally {
            executor.shutdown();
        }
    }
}

Esercizio 5: Utilizzo di CountDownLatch

Utilizzare `CountDownLatch` per sincronizzare l'esecuzione di più thread.
import java.util.concurrent.CountDownLatch;

public class CountDownLatchEsempio {
    public static void main(String[] args) {
        CountDownLatch latch = new CountDownLatch(3);

        Runnable task = () -> {
            try {
                Thread.sleep(1000);
                System.out.println(Thread.currentThread().getName() + " completato");
                latch.countDown();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };

        for (int i = 0; i < 3; i++) {
            new Thread(task).start();
        }

        try {
            latch.await();
            System.out.println("Tutti i thread sono completati");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Esercizio 6: Esecuzione Periodica con ScheduledExecutorService

Utilizzare `ScheduledExecutorService` per eseguire un task periodicamente.
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ScheduledTask {
    public static void main(String[] args) {
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

        Runnable task = () -> {
            System.out.println("Esecuzione del task: " + Thread.currentThread().getName());
        };

        scheduler.scheduleAtFixedRate(task, 0, 1, TimeUnit.SECONDS);

        // Eseguire il task periodico per 5 secondi prima di spegnere il scheduler
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            scheduler.shutdown();
        }
    }
}