In Java il multithreading consente l'esecuzione simultanea delle attività, migliorando le prestazioni e la reattività. Tradizionalmente gli sviluppatori utilizzavano l'interfaccia Runnable per definire le attività, ma presenta due limitazioni principali: non può restituire un risultato e non può generare eccezioni verificate. Per superare questi problemi Java ha introdotto le interfacce Callable e Future in Java 5.
Interfaccia richiamabile
IL Interfaccia richiamabile rappresenta un'attività che restituisce un risultato e può generare un'eccezione. È simile a Runnable ma più flessibile poiché può restituire un valore e generare eccezioni controllate.
Javaimport java.util.concurrent.*; public class CallableExample { public static void main(String[] args) throws Exception { ExecutorService executor = Executors.newSingleThreadExecutor(); Callable<Integer> task = () -> { int sum = 0; for (int i = 1; i <= 5; i++) sum += i; return sum; // returns result }; Future<Integer> future = executor.submit(task); System.out.println('Result: ' + future.get()); executor.shutdown(); } }
Produzione
Result: 15
Spiegazione: Un'attività Callable viene inviata all'esecutore. Calcola la somma dei numeri da 1 a 5 e restituisce il risultato. Il risultato viene recuperato utilizzando future.get() al termine dell'attività.
Interfaccia futura
IL Interfaccia futura rappresenta il risultato di un calcolo asincrono. Quando invii un'attività Callable o Runnable a un ExecutorService, restituisce un oggetto Future.
Javaimport java.util.concurrent.*; public class CallableFutureExample { public static void main(String[] args) { ExecutorService executor = Executors.newSingleThreadExecutor(); Future<Integer> future = executor.submit(() -> 10 + 20); try { Integer result = future.get(); // waits but returns instantly System.out.println('Result: ' + result); } catch (Exception e) { e.printStackTrace(); } finally { executor.shutdown(); } } }
Produzione
Result: 30
Spiegazione: ILCallablecalcoli del compito10 + 2 and ExecutorService.submit()il metodo restituisce aFutureoggetto. Utilizzandofuture.get()otteniamo il risultato una volta completato il calcolo.
Chiamabile vs futuro
| Caratteristica | Chiamabile | Futuro |
|---|---|---|
| Scopo | Rappresenta un'attività che restituisce un risultato | Rappresenta il risultato di un'attività asincrona |
| Tipo di reso | Restituisce un risultato quando eseguito | Contiene il risultato restituito da un Callable |
| Definito dentro | pacchetto java.util.concurrent | pacchetto java.util.concurrent |
| Esecuzione | Inviato a ExecutorService | Restituito da ExecutorService.submit() |
| Metodi | Ha una chiamata al metodo() | Ha metodi come get() isDone() cancel() |
| Gestione delle eccezioni | Può lanciare eccezioni controllate | Gestisce i risultati e le eccezioni dopo l'esecuzione |
| Utilizzo | Definisce cosa eseguire | Controls monitora e recupera il risultato di un'attività |