[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"question-mnogopotochnost-chto-takoe-completablefuture-i-kak-on-rabotaet":3},{"id":4,"slug":5,"topicId":6,"topicSlug":7,"topicName":8,"topicEmoji":9,"question":10,"answer":11,"codeLang":12,"codeSrc":12,"important":12,"commonMistakes":12,"modernUsage":12,"difficulty":13,"tags":14,"related":20,"progress":21,"seo":22},293,"chto-takoe-completablefuture-i-kak-on-rabotaet",8,"mnogopotochnost","Многопоточность","🔀","Что такое CompletableFuture и как он работает?","\u003C!-- grade: 5\u002F5 — подробный, хорошо структурированный ответ -->\n\n`CompletableFuture` — это класс из `java.util.concurrent` (Java 8), реализующий интерфейсы `Future` и `CompletionStage`. Он представляет результат асинхронного вычисления, который можно явно завершить, и предоставляет богатый API для построения цепочек асинхронных операций.\n\n**Отличие от обычного `Future`:** `Future` (Java 5) позволяет лишь проверить завершённость и получить результат блокирующим вызовом `get()`. `CompletableFuture` добавляет:\n- Неблокирующие цепочки операций (`thenApply`, `thenCompose`)\n- Комбинирование нескольких задач (`thenCombine`, `allOf`, `anyOf`)\n- Обработку ошибок в функциональном стиле (`exceptionally`, `handle`)\n- Возможность ручного завершения (`complete()`, `completeExceptionally()`)\n\n**Принцип работы — «обещание» (promise):**\n\n```java\n\u002F\u002F Создание и ручное завершение\nCompletableFuture\u003CString> future = new CompletableFuture\u003C>();\n\u002F\u002F В другом потоке:\nfuture.complete(\"Результат\");\n\u002F\u002F Или при ошибке:\nfuture.completeExceptionally(new RuntimeException(\"Ошибка\"));\n\n\u002F\u002F Создание с автоматическим выполнением в ForkJoinPool.commonPool()\nCompletableFuture\u003CString> asyncFuture = CompletableFuture.supplyAsync(() -> {\n    \u002F\u002F длительная операция\n    return \"Результат асинхронного вычисления\";\n});\n\n\u002F\u002F С явным пулом потоков\nExecutorService executor = Executors.newFixedThreadPool(4);\nCompletableFuture\u003CString> customPoolFuture = CompletableFuture.supplyAsync(() -> {\n    return \"Результат в custom pool\";\n}, executor);\n```\n\n**Построение цепочек:**\n\n```java\nCompletableFuture\u003CString> result = CompletableFuture\n    .supplyAsync(() -> fetchDataFromDB())       \u002F\u002F Асинхронно получить данные\n    .thenApply(data -> transform(data))          \u002F\u002F Преобразовать результат\n    .thenApply(transformed -> format(transformed)) \u002F\u002F Отформатировать\n    .exceptionally(ex -> \"Значение по умолчанию\"); \u002F\u002F Обработать ошибку\n```\n\n**Комбинирование нескольких CompletableFuture:**\n\n```java\nCompletableFuture\u003CString> future1 = CompletableFuture.supplyAsync(() -> \"Привет\");\nCompletableFuture\u003CString> future2 = CompletableFuture.supplyAsync(() -> \" Мир\");\n\n\u002F\u002F Комбинирование двух результатов\nCompletableFuture\u003CString> combined = future1.thenCombine(future2, (s1, s2) -> s1 + s2);\nSystem.out.println(combined.get()); \u002F\u002F \"Привет Мир\"\n\n\u002F\u002F Ожидание завершения всех\nCompletableFuture\u003CVoid> all = CompletableFuture.allOf(future1, future2);\n\n\u002F\u002F Ожидание первого завершённого\nCompletableFuture\u003CObject> any = CompletableFuture.anyOf(future1, future2);\n```\n\n**Ключевые нюансы:**\n- По умолчанию используется `ForkJoinPool.commonPool()`. Для IO-задач рекомендуется передавать собственный `ExecutorService`.\n- Методы с суффиксом `Async` (например, `thenApplyAsync`) выполняют следующий шаг в отдельном потоке, без суффикса — в потоке, завершившем предыдущий шаг.\n- `CompletableFuture` можно завершить вручную через `complete()`, что удобно для интеграции с callback-based API.\n- Цепочки операций формируют направленный ациклический граф (DAG) зависимостей.\n\n**Частые ошибки:**\n- `get()` без таймаута — может заблокировать поток навсегда. Используйте `get(timeout, unit)` или `join()`.\n- Игнорирование исключений — без `exceptionally()` или `handle()` исключение обнаружится только при `get()`.\n- Блокирующие IO в `ForkJoinPool.commonPool()` — это общий пул, блокировка его потоков приводит к голоданию.\n\n**Актуальность в 2026:** `CompletableFuture` остаётся основным инструментом для оркестрации асинхронных задач. С Virtual Threads (Java 21+) необходимость в нём для простых IO-задач снижается, но для сложных сценариев комбинирования он по-прежнему незаменим.\n\n> **Аналогия:** `CompletableFuture` — это заказ в ресторане. Вы оформляете заказ (supplyAsync) и получаете номерок (объект future). Пока заказ готовится, вы можете добавить просьбу «когда будет готово — подогрейте» (thenApply), «если не получится — принесите альтернативу» (exceptionally). Когда блюдо готово, вся цепочка инструкций выполняется автоматически.\n\n> **На собеседовании** часто спрашивают: «В каком потоке выполняется `thenApply`?» Ответ: в потоке, завершившем предыдущий этап, или в вызывающем потоке, если future уже завершён. Для гарантированного выполнения в пуле используйте `thenApplyAsync`.","","middle",[15,16,17,18,19],"CompletableFuture","Future","асинхронность","CompletionStage","concurrency",[],null,{"title":23,"description":24,"ogTitle":25,"ogDescription":26,"keywords":27,"schemaAnswer":32,"featuredSnippetReady":33},"Что такое CompletableFuture в Java — принцип работы и примеры — Gymterview","CompletableFuture (Java 8) — результат асинхронного вычисления с API для цепочек операций, комбинирования задач и обработки ошибок в функциональном стиле.","CompletableFuture в Java — асинхронные цепочки операций","CompletableFuture позволяет строить цепочки асинхронных операций, комбинировать задачи через thenCombine\u002FallOf и обрабатывать ошибки через exceptionally\u002Fhandle.",[28,29,30,31,18],"CompletableFuture Java","асинхронное программирование","supplyAsync","thenApply","CompletableFuture (Java 8) реализует Future и CompletionStage. Работает по принципу «обещания» (promise): объект создаётся до получения результата и завершается позднее — автоматически через supplyAsync\u002FrunAsync или вручную через complete(). Поддерживает цепочки операций (thenApply, thenCompose), комбинирование (thenCombine, allOf, anyOf) и обработку ошибок (exceptionally, handle). По умолчанию использует ForkJoinPool.commonPool().",true]