Pratica del multithreading in modo serio: passiamo le attività a
ExecutorService invece della creazione manuale di
Thread, gestiamo il pool, la coda e il ciclo di vita (
shutdown(),
shutdownNow()). Analizziamo la differenza tra
Runnable e
Callable<T>, otteniamo i risultati tramite
Future e i suoi metodi (
get(),
isDone(),
cancel(...),
isCancelled()). Mostreremo l'esecuzione di più attività,
invokeAll/
invokeAny, la gestione di
ExecutionException e gli errori tipici.