Приходилось ли использовать примитивы синхронизации в многопоточности? Расскажи про CountDownLatch, CyclicBarrier, Phaser и другие
Ответ от нейросети
sobes.tech AI
В многопоточном программировании примитивы синхронизации помогают координировать работу потоков и управлять их взаимодействием.
CountDownLatch — это счетчик, который позволяет одному или нескольким потокам ждать, пока другие потоки выполнят определённое количество операций. Например, если у вас есть 3 потока, которые должны завершить подготовку, а главный поток ждёт их завершения, то CountDownLatch инициализируется значением 3, и каждый поток вызывает countDown() по окончании работы. Главный поток вызывает await() и блокируется, пока счетчик не станет 0.
CyclicBarrier — барьер, который заставляет группу потоков ждать друг друга, пока все не достигнут определённой точки. После этого барьер сбрасывается и может использоваться повторно. Это удобно, когда нужно синхронизировать фазы работы потоков.
Phaser — более гибкий примитив, объединяющий возможности CountDownLatch и CyclicBarrier. Позволяет динамически добавлять и удалять участники, поддерживает несколько фаз синхронизации.
Пример использования CountDownLatch на Java:
CountDownLatch latch = new CountDownLatch(3);
Runnable task = () -> {
// Выполнение задачи
System.out.println(Thread.currentThread().getName() + " готов");
latch.countDown();
};
new Thread(task).start();
new Thread(task).start();
new Thread(task).start();
latch.await(); // Ждем, пока все три потока вызовут countDown
System.out.println("Все потоки готовы, продолжаем работу");
Другие примитивы: семафоры (Semaphore) для ограничения количества одновременно работающих потоков, мьютексы (Mutex) для взаимного исключения доступа к ресурсам.