[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"question-mnogopotochnost-chto-takoe-exchanger-i-dlya-chego-on-ispolzuetsya":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},302,"chto-takoe-exchanger-i-dlya-chego-on-ispolzuetsya",8,"mnogopotochnost","Многопоточность","🔀","Что такое Exchanger и для чего он используется?","\u003C!-- grade: 4\u002F5 — хороший ответ, добавлена практическая мотивация -->\n\n`Exchanger\u003CV>` — это синхронизатор из `java.util.concurrent`, предназначенный для **обмена данными между ровно двумя потоками**. Каждый поток вызывает `exchange()`, передавая свой объект, и блокируется до тех пор, пока второй поток не вызовет тот же метод. После этого каждый получает объект, переданный другим.\n\n\u003Cdetails>\n\u003Csummary>Код: простой обмен между двумя потоками\u003C\u002Fsummary>\n\n```java\nExchanger\u003CString> exchanger = new Exchanger\u003C>();\n\nThread producer = new Thread(() -> {\n    try {\n        String data = \"Данные от производителя\";\n        String received = exchanger.exchange(data); \u002F\u002F Блокируется до обмена\n        System.out.println(\"Производитель получил: \" + received);\n    } catch (InterruptedException e) {\n        Thread.currentThread().interrupt();\n    }\n});\n\nThread consumer = new Thread(() -> {\n    try {\n        String data = \"Подтверждение от потребителя\";\n        String received = exchanger.exchange(data);\n        System.out.println(\"Потребитель получил: \" + received);\n    } catch (InterruptedException e) {\n        Thread.currentThread().interrupt();\n    }\n});\n\nproducer.start();\nconsumer.start();\n```\n\n\u003C\u002Fdetails>\n\n**Практический пример — двойная буферизация:**\n\n\u003Cdetails>\n\u003Csummary>Код: producer-consumer с обменом буферами\u003C\u002Fsummary>\n\n```java\nExchanger\u003CList\u003CString>> exchanger = new Exchanger\u003C>();\n\n\u002F\u002F Производитель заполняет буфер и обменивается пустым\nThread producer = new Thread(() -> {\n    List\u003CString> buffer = new ArrayList\u003C>();\n    try {\n        while (true) {\n            buffer.add(generateData());\n            if (buffer.size() >= 100) {\n                buffer = exchanger.exchange(buffer); \u002F\u002F Отдаёт полный, получает пустой\n                buffer.clear();\n            }\n        }\n    } catch (InterruptedException e) {\n        Thread.currentThread().interrupt();\n    }\n});\n\n\u002F\u002F Потребитель обрабатывает полный буфер и возвращает пустой\nThread consumer = new Thread(() -> {\n    List\u003CString> buffer = new ArrayList\u003C>();\n    try {\n        while (true) {\n            buffer = exchanger.exchange(buffer); \u002F\u002F Отдаёт пустой, получает полный\n            processData(buffer);\n        }\n    } catch (InterruptedException e) {\n        Thread.currentThread().interrupt();\n    }\n});\n```\n\n\u003C\u002Fdetails>\n\n**Метод с таймаутом:**\n\n```java\nString received = exchanger.exchange(data, 5, TimeUnit.SECONDS);\n\u002F\u002F TimeoutException, если второй поток не вызвал exchange() за 5 секунд\n```\n\n**Ключевые особенности:**\n- Работает строго между **двумя** потоками. Третий поток будет ждать четвёртого.\n- Обмен атомарен — оба потока гарантированно получат объекты друг друга.\n- Используйте версию с таймаутом в production, чтобы избежать вечной блокировки.\n\n**Частые ошибки:**\n- Использование с >2 потоками — непредсказуемое поведение.\n- Отсутствие обработки `InterruptedException` — `exchange()` прерываема.\n- Забытый таймаут — вечная блокировка при отсутствии партнёра.\n\n> **Аналогия:** `Exchanger` — это точка обмена шпионов на мосту. Каждая сторона (поток) приводит своего человека (данные) и ждёт на мосту, пока другая сторона не придёт со своим. Обмен происходит одновременно.\n\n> **На собеседовании** `Exchanger` — это нишевый инструмент. Упомяните его применение в двойной буферизации и pipeline-обработке. В большинстве новых проектов заменяется на `BlockingQueue` или `CompletableFuture`.","","middle",[15,16,17,18,19],"двойная-буферизация","обмен-данными","Exchanger","синхронизатор","concurrency",[],null,{"title":23,"description":24,"ogTitle":25,"ogDescription":26,"keywords":27,"schemaAnswer":33,"featuredSnippetReady":34},"Exchanger в Java — обмен данными между двумя потоками — Gymterview","Exchanger — синхронизатор для обмена объектами между двумя потоками. Метод exchange() блокирует до встречного вызова. Применяется в двойной буферизации.","Exchanger — парный обмен данными между потоками в Java","Exchanger позволяет двум потокам атомарно обменяться объектами. exchange() блокируется, пока второй поток не вызовет тот же метод.",[28,29,30,31,32],"Exchanger Java","обмен данными потоки","exchange метод","двойная буферизация Java","парная синхронизация","Exchanger\u003CV> — синхронизатор для обмена данными между двумя потоками. Каждый поток вызывает exchange(), передавая свой объект и блокируясь до ответного вызова. После встречи каждый получает объект другого. Обмен атомарен. Работает строго для двух потоков. Используйте версию с таймаутом в production. Применяется в двойной буферизации, pipeline-обработке.",true]