Storia della domanda:
In Java il supporto per la multithreading è stato implementato fin dall'inizio. I thread consentono di eseguire più attività in parallelo, utilizzando in modo efficiente i processori multicore. La JVM fornisce uno strato di astrazione sui thread del sistema operativo.
Problema:
La creazione, gestione e terminazione dei thread richiede una chiara comprensione del loro ciclo di vita, sincronizzazione e possibili stati di race condition. Un uso imprudente dei thread può portare a deadlock, accesso errato alle risorse e log di errore complessi.
Soluzione:
In Java i thread possono essere creati estendendo la classe Thread o implementando l'interfaccia Runnable, oltre che tramite strumenti moderni come ExecutorService. È importante terminare correttamente i thread, gestire il loro ciclo di vita e sincronizzare l'accesso ai dati condivisi.
Esempio di creazione e terminazione di un thread:
class MyRunnable implements Runnable { public void run() { System.out.println("Thread is running"); } } public class ThreadExample { public static void main(String[] args) { Thread t = new Thread(new MyRunnable()); t.start(); // avvio del thread try { t.join(); // attesa della terminazione } catch (InterruptedException e) { e.printStackTrace(); } } }
Caratteristiche chiave:
start(), non run() (altrimenti non ci sarà vera parallelità)join()IllegalThreadStateExceptionÈ possibile riavviare un thread dopo la terminazione?
No. Dopo la terminazione, il thread è considerato "morto", il riavvio di start() porterà a IllegalThreadStateException.
Qual è la differenza tra la chiamata a t.run() e t.start()?
t.run() chiamerà semplicemente il metodo run nel thread corrente, senza creare un nuovo thread di esecuzione. Solo t.start() crea un thread separato del sistema operativo.
Cosa succede se un thread termina con un'eccezione non gestita?
Se viene generata un'eccezione non gestita, il thread terminerà in modo anomalo, il suo stack trace verrà stampato nel flusso di errore, gli altri thread non saranno interessati.
run() invece di start()InterruptedException)Un programmatore avvia un thread con il metodo run(), pensando che funzioni in parallelo con main, ma in realtà tutto viene eseguito in sequenza.
Pro:
Contro:
Uso corretto di start(), gestione adeguata delle eccezioni, utilizzo di join() per attendere la terminazione dei thread.
Pro:
Contro: