[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"question-mnogopotochnost-chto-takoe-futuretask":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":21,"progress":22,"seo":23},257,"chto-takoe-futuretask",8,"mnogopotochnost","Многопоточность","🔀","Что такое FutureTask?","\u003C!-- grade: 3\u002F5 — определение правильное, но нет примера и не раскрыта связь с Callable\u002FRunnable -->\n\n**`FutureTask\u003CV>`** -- это класс, реализующий одновременно интерфейсы `Future\u003CV>` и `Runnable`. Он представляет собой **отменяемое асинхронное вычисление**, которое можно запустить в отдельном потоке и получить результат, когда он будет готов.\n\n### Иерархия\n\n```\nRunnable ──┐\n           ├──▶ RunnableFuture\u003CV> ──▶ FutureTask\u003CV>\nFuture\u003CV> ─┘\n```\n\n### Конструкторы\n\n```java\n\u002F\u002F Обёртка над Callable — результат берётся из call()\nFutureTask\u003CString> task1 = new FutureTask\u003C>(() -> \"Результат\");\n\n\u002F\u002F Обёртка над Runnable — при завершении вернёт указанный result\nFutureTask\u003CString> task2 = new FutureTask\u003C>(() -> {\n    System.out.println(\"Работаю\");\n}, \"Готово\");\n```\n\n### Основные методы\n\n| Метод | Описание |\n|---|---|\n| `run()` | Выполняет вычисление (из `Runnable`) |\n| `get()` | Блокирует текущий поток до получения результата |\n| `get(long timeout, TimeUnit unit)` | Блокирует с таймаутом, выбрасывает `TimeoutException` |\n| `cancel(boolean mayInterruptIfRunning)` | Отменяет задачу. Если `true` и задача выполняется -- прерывает поток |\n| `isCancelled()` | Была ли задача отменена |\n| `isDone()` | Завершена ли задача (успешно, с ошибкой или отменена) |\n\n### Способы запуска\n\n\u003Cdetails>\n\u003Csummary>Пример: три способа запуска FutureTask\u003C\u002Fsummary>\n\n```java\npublic class FutureTaskDemo {\n    public static void main(String[] args) throws Exception {\n        Callable\u003CInteger> computation = () -> {\n            Thread.sleep(2000);\n            return 42;\n        };\n\n        \u002F\u002F Способ 1: через Thread\n        FutureTask\u003CInteger> task1 = new FutureTask\u003C>(computation);\n        new Thread(task1).start();\n        System.out.println(\"Результат (Thread): \" + task1.get());\n\n        \u002F\u002F Способ 2: через ExecutorService\n        FutureTask\u003CInteger> task2 = new FutureTask\u003C>(computation);\n        ExecutorService executor = Executors.newSingleThreadExecutor();\n        executor.submit(task2);\n        System.out.println(\"Результат (Executor): \" + task2.get());\n        executor.shutdown();\n\n        \u002F\u002F Способ 3: прямой вызов run() (в текущем потоке)\n        FutureTask\u003CInteger> task3 = new FutureTask\u003C>(computation);\n        task3.run(); \u002F\u002F Блокирует текущий поток\n        System.out.println(\"Результат (run): \" + task3.get());\n    }\n}\n```\n\n\u003C\u002Fdetails>\n\n### Особенности\n\n1. **Одноразовость** -- `FutureTask` выполняется ровно один раз. Повторный вызов `run()` не приводит к повторному вычислению.\n2. **Потокобезопасность** -- `get()` можно вызывать из нескольких потоков одновременно; все они получат один и тот же результат.\n3. **Хранение исключения** -- если `call()` выбросил исключение, `get()` обернёт его в `ExecutionException`.\n4. **Переопределяемый `done()`** -- защищённый метод `done()` вызывается после завершения задачи и может быть переопределён для получения уведомлений.\n\n> **Аналогия из жизни.** `FutureTask` -- это квитанция из химчистки: вы сдаёте вещь (задачу), получаете квитанцию (объект `FutureTask`), и позже приходите за результатом. Если результат ещё не готов, вы ждёте (`get()` блокируется). Если передумали -- можете отменить заказ (`cancel()`), но только если вещь ещё не обработали.\n\n> **На собеседовании.** Покажите, что `FutureTask` объединяет `Runnable` и `Future` -- поэтому его можно и передать в `Thread`, и использовать для получения результата. На практике в современном коде чаще используют `CompletableFuture` (Java 8+), который поддерживает композицию и цепочки асинхронных операций. `FutureTask` остаётся полезным для низкоуровневого контроля (например, кэширование результатов вычислений).","","middle",[15,16,17,18,19,20],"FutureTask","Runnable","Future","асинхронность","Callable","concurrency",[],null,{"title":24,"description":25,"ogTitle":26,"ogDescription":27,"keywords":28,"schemaAnswer":33,"featuredSnippetReady":34},"FutureTask в Java — отменяемое асинхронное вычисление — Gymterview","FutureTask — базовая реализация Future. Оборачивает Callable или Runnable, предоставляет методы запуска, остановки и получения результата вычисления.","FutureTask — обёртка для асинхронных вычислений","FutureTask реализует Future и Runnable. Оборачивает Callable\u002FRunnable, позволяет запускать, отменять и получать результат вычисления.",[29,30,31,32],"FutureTask Java","FutureTask пример","Future Callable обёртка","асинхронное вычисление Java","FutureTask — отменяемое асинхронное вычисление с базовой реализацией Future. Оборачивает Callable и Runnable, предоставляет методы запуска и остановки вычисления, получения результата. Результат доступен только после завершения — get() блокируется до этого момента. Реализует Runnable и может быть передан в Executor.",true]