Sobes.tech
Назад к вопросам
Senior
11

Приходилось ли использовать примитивы синхронизации в многопоточности? Расскажи про 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) для взаимного исключения доступа к ресурсам.