[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"question-mnogopotochnost-sushchestvuet-li-sposob-resheniya-problemy-race-condition":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},260,"sushchestvuet-li-sposob-resheniya-problemy-race-condition",8,"mnogopotochnost","Многопоточность","🔀","Существует ли способ решения проблемы race condition?","\u003C!-- grade: 4\u002F5 — способы перечислены, но можно структурировать лучше и дополнить -->\n\nДа, существует несколько способов решения. Выбор зависит от конкретного сценария.\n\n### Основные способы\n\n#### 1. Синхронизация (synchronized)\n\nОперации над разделяемым ресурсом помещаются в `synchronized` блок, гарантирующий взаимное исключение и видимость:\n\n```java\npublic class SafeCounter {\n    private int count = 0;\n\n    public synchronized void increment() {\n        count++; \u002F\u002F Теперь атомарно\n    }\n\n    public synchronized int getCount() {\n        return count;\n    }\n}\n```\n\n#### 2. Атомарные переменные\n\nКлассы `java.util.concurrent.atomic` обеспечивают атомарность без блокировок:\n\n```java\nprivate final AtomicInteger count = new AtomicInteger(0);\n\npublic void increment() {\n    count.incrementAndGet(); \u002F\u002F Атомарная CAS-операция\n}\n```\n\n#### 3. volatile + однократная запись\n\nЕсли переменная записывается одним потоком, а читается многими, достаточно `volatile`:\n\n```java\nprivate volatile boolean ready = false;\n\n\u002F\u002F Поток-писатель\npublic void prepareData() {\n    data = loadData();\n    ready = true; \u002F\u002F Все потоки-читатели увидят это\n}\n```\n\n#### 4. Потокобезопасные коллекции\n\nИспользование конкурентных коллекций из `java.util.concurrent`:\n\n```java\n\u002F\u002F Вместо HashMap + synchronized\nConcurrentHashMap\u003CString, Integer> map = new ConcurrentHashMap\u003C>();\nmap.computeIfAbsent(\"key\", k -> expensiveComputation(k)); \u002F\u002F Атомарная операция\n```\n\n#### 5. Неизменяемые объекты (Immutable objects)\n\nОбъекты, состояние которых нельзя изменить после создания, свободны от race condition по определению:\n\n```java\npublic record Point(int x, int y) { }\n\u002F\u002F Нет сеттеров, нет мутабельного состояния — нет гонок\n```\n\n#### 6. ThreadLocal\n\nЕсли каждому потоку нужна своя копия переменной:\n\n```java\nprivate static final ThreadLocal\u003CSimpleDateFormat> formatter =\n    ThreadLocal.withInitial(() -> new SimpleDateFormat(\"yyyy-MM-dd\"));\n```\n\n### Сводная таблица\n\n| Способ | Блокировка | Подходит для | Производительность |\n|---|---|---|---|\n| `synchronized` | Да | Сложные составные операции | Средняя |\n| `ReentrantLock` | Да | Составные операции с таймаутом, tryLock | Средняя |\n| `Atomic*` | Нет (lock-free) | Простые read-modify-write | Высокая |\n| `volatile` | Нет | Одна запись — много чтений | Высокая |\n| Concurrent-коллекции | Частично | Конкурентный доступ к коллекциям | Высокая |\n| Immutable objects | Нет | Передача данных между потоками | Высокая |\n| `ThreadLocal` | Нет | Изоляция данных по потокам | Высокая |\n\n> **Аналогия из жизни.** Проблема: два человека одновременно редактируют один документ. Решения: (1) `synchronized` -- очередь к одному принтеру, (2) `Atomic` -- каждый исправляет только своё слово атомарно, (3) Immutable -- никто не редактирует, а создаёт новую версию, (4) `ThreadLocal` -- у каждого своя копия документа.\n\n> **На собеседовании.** Не ограничивайтесь одним способом -- покажите, что знаете несколько подходов и умеете выбирать: для простого флага -- `volatile`, для счётчика -- `AtomicInteger`, для сложной логики -- `synchronized` или `ReentrantLock`. Подчеркните, что лучший способ избежать гонок -- правильное проектирование: минимизация разделяемого состояния и использование неизменяемых объектов.","","middle",[15,16,17,18,19],"synchronized","race condition","синхронизация","volatile","concurrency",[],null,{"title":23,"description":24,"ogTitle":25,"ogDescription":26,"keywords":27,"schemaAnswer":32,"featuredSnippetReady":33},"Как решить race condition в Java — 3 способа — Gymterview","Три подхода: локальная копия переменной с volatile, синхронизированный блок (synchronized), комбинирование обоих методов. Лучшее решение — правильное проектирование.","Решение race condition — volatile, synchronized и комбинация","Локальная копия с volatile, синхронизация через synchronized, комбинирование методов. Лучшая защита — правильная архитектура.",[28,29,30,31],"решение race condition Java","как избежать race condition","synchronized race condition","volatile race condition","Три способа: 1) локальная копия переменной (volatile) — работает для одной атомарной переменной; 2) синхронизация через synchronized; 3) комбинирование — копирование в синхронизированном блоке. Лучший способ — правильное проектирование многозадачной системы.",true]