Какие способы синхронизации в Java вы знаете?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
В Java существует несколько основных механизмов синхронизации для управления доступом к общим ресурсам из разных потоков:
-
synchronizedключевое слово: Может применяться к методам и блокам кода. Обеспечивает атомарность и видимость.// Синхронизация метода public synchronized void increment() { count++; } // Синхронизация блока кода public void updateList() { synchronized (myList) { myList.add(newItem); } } -
Явные блокировки (
java.util.concurrent.locks)-
ReentrantLock: Реентерабельная, позволяет выполнять блокировку несколько раз одним потоком.import java.util.concurrent.locks.ReentrantLock; private final ReentrantLock lock = new ReentrantLock(); public void performTask() { lock.lock(); try { // Критическая секция } finally { lock.unlock(); } } -
ReentrantReadWriteLock: Разделяет блокировку на чтение и запись, позволяя нескольким потокам читать одновременно, но только одному записывать.import java.util.concurrent.locks.ReentrantReadWriteLock; private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock(); private final ReentrantReadWriteLock.ReadLock readLock = rwLock.readLock(); private final ReentrantReadWriteLock.WriteLock writeLock = rwLock.writeLock(); public void readData() { readLock.lock(); try { // Чтение данных } finally { readLock.unlock(); } } public void writeData() { writeLock.lock(); try { // Запись данных } finally { writeLock.unlock(); } }
-
-
Семафоры (
Semaphore): Ограничивают количество потоков, которые могут одновременно получить доступ к определенному ресурсу.import java.util.concurrent.Semaphore; private final Semaphore semaphore = new Semaphore(5); // Разрешаем 5 потокам public void accessResource() throws InterruptedException { semaphore.acquire(); // Запрашиваем разрешение try { // Работа с ресурсом } finally { semaphore.release(); // Освобождаем разрешение } } -
Мьютексы (
Mutex): Хотя в Java нет отдельного классаMutex,ReentrantLockчасто используется как аналог мьютекса (блокировка только одним потоком). -
Объекты для синхронизации потоков (
java.util.concurrent)-
CountDownLatch: Позволяет одному или нескольким потокам ждать, пока определенное количество операций не завершится.import java.util.concurrent.CountDownLatch; private final CountDownLatch latch = new CountDownLatch(3); // Ждем 3 завершения // Потоки выполняют задачи и уменьшают счетчик: latch.countDown(); // Поток-ожидатель: latch.await(); -
CyclicBarrier: Позволяет группе потоков ждать друг друга в определенной точке перед тем, как продолжить выполнение.import java.util.concurrent.CyclicBarrier; private final CyclicBarrier barrier = new CyclicBarrier(4); // Барьер для 4 потоков // Потоки выполняют задачи и достигают барьера: barrier.await(); -
Exchanger: Позволяет двум потокам обмениваться объектами в точке синхронизации.import java.util.concurrent.Exchanger; private final Exchanger<String> exchanger = new Exchanger<>(); // В одном потоке: String received = exchanger.exchange("Отправляю"); // В другом потоке: String received = exchanger.exchange("Получаю");
-
-
Синхронизированные коллекции (
Collections.synchronized...)- Оборачивают обычные коллекции, делая их потокобезопасными.
- Пример:
Collections.synchronizedList(new ArrayList<>())
-
Потокобезопасные коллекции (
java.util.concurrent)- Предоставляют более высокопроизводительные и гибкие альтернативы синхронизированным коллекциям.
- Примеры:
ConcurrentHashMap,CopyOnWriteArrayList,BlockingQueue(например,ArrayBlockingQueue,LinkedBlockingQueue).
Выбор метода синхронизации зависит от конкретной задачи и требований к производительности и атомарности.