Ответ
Асинхронное выполнение кода в Java Core обеспечивается следующими основными механизмами:
-
Потоки (Threads) и Runnable/Callable: Базовый низкоуровневый API.
Thread thread = new Thread(() -> { System.out.println("Выполняется в фоне"); }); thread.start(); // Асинхронный запуск -
Executor Framework и Future: Пул потоков для управления ресурсами и
Futureдля представления отложенного результата.ExecutorService executor = Executors.newFixedThreadPool(2); Future<Integer> future = executor.submit(() -> { Thread.sleep(1000); return 42; }); // Блокирующий вызов для получения результата Integer result = future.get(); executor.shutdown(); -
CompletableFuture (Java 8+): Современный API для композиции асинхронных операций без блокировки.
CompletableFuture.supplyAsync(() -> "data") .thenApplyAsync(data -> data.toUpperCase()) // Асинхронное преобразование .thenAcceptAsync(result -> System.out.println(result)) // Асинхронное потребление .exceptionally(ex -> { System.err.println(ex); return null; }); // Обработка ошибок
Ключевые различия и best practices:
- Прямое создание
Threadнеэффективно для множества коротких задач. Всегда предпочитайте пулы (ExecutorService). Future.get()блокирует вызывающий поток.CompletableFutureпозволяет строить цепочки без блокировок.CompletableFutureпо умолчанию используетForkJoinPool.commonPool(). Для задач, блокирующих IO, лучше использовать свой пул.- Всегда закрывайте
ExecutorService(shutdown()илиshutdownNow()).