Какие механизмы в Java Core реализуют асинхронное программирование?

«Какие механизмы в Java Core реализуют асинхронное программирование?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Асинхронное выполнение кода в Java Core обеспечивается следующими основными механизмами:

  1. Потоки (Threads) и Runnable/Callable: Базовый низкоуровневый API.

    Thread thread = new Thread(() -> {
        System.out.println("Выполняется в фоне");
    });
    thread.start(); // Асинхронный запуск
  2. 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();
  3. 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()).