Я читал через API java.util.concurrent и обнаружил, что
CountDownLatch
: Средство синхронизации, позволяющее одному или нескольким потокам дождаться завершения набора операций, выполняемых в других потоках.CyclicBarrier
: Средство синхронизации, которое позволяет всем потокам ожидать друг друга, чтобы достичь общей барьерной точки.
Мне обоим кажется равным, но я уверен, что это намного больше.
Например, в CoundownLatch, the countdown value could not be reset, that can happen in the case of CyclicBarrier
.
Есть ли другая разница между ними?
В каком месте use cases
кто-то захочет сбросить значение обратного отсчета?
java
concurrency
countdownlatch
cyclicbarrier
мечтатель
источник
источник
Ответы:
Одно из основных отличий состоит в том, что CyclicBarrier выполняет (необязательную) Runnable задачу, которая запускается при выполнении общего барьерного условия.
Это также позволяет узнать количество клиентов, ожидающих на барьере, и количество, необходимое для запуска барьера. После срабатывания шлагбаум сбрасывается и может быть использован снова.
Для простых случаев использования - запуск служб и т. Д. CyclicBarrier полезен для более сложных задач координации. Примером такой вещи могут быть параллельные вычисления - где в вычислении участвуют несколько подзадач - что-то вроде MapReduce .
источник
Есть еще одно отличие.
При использовании a
CyclicBarrier
предполагается, что вы указываете количество ожидающих потоков, которые запускают барьер. Если вы укажете 5, у вас должно быть как минимум 5 потоков для вызоваawait()
.При использовании a
CountDownLatch
вы указываете количество вызовов,countDown()
которые приведут к освобождению всех ожидающих потоков. Это означает, что вы можете использоватьCountDownLatch
только один поток.«Зачем ты это делаешь?», Скажете вы. Представьте, что вы используете таинственный API, закодированный кем-то еще, который выполняет обратные вызовы. Вы хотите, чтобы один из ваших потоков ожидал, пока определенный обратный вызов не будет вызван несколько раз. Вы не представляете, в каких потоках будет вызываться обратный вызов. В этом случае a
CountDownLatch
идеально, тогда как я не могу придумать, как реализовать это с помощью aCyclicBarrier
(на самом деле, я могу, но это связано с таймаутами ... хм!)Я просто хочу, чтобы это
CountDownLatch
можно было сбросить!источник
CountDownLatch
неплохо сбросить настройки - обходной путь, который я использую для реализации грубого уведомления об ожидании, - это просто обновитьCountDownLatch
сразу же, когда вводится защищенный кодовый блок (когда защелка достигает нуля). Конечно, это не применимо при любых обстоятельствах / масштабах, но я подумал, что стоит отметить, что это вариант в ситуациях с златовлаской шкурой.Java Concurrency in Practice
- говорит то же самоеLatches are for waiting for events; barriers are for waiting for other threads.
. Основной и важный момент, чтобы понять разницу между этими двумя.Один момент, который еще никто не упомянул, заключается в том, что
CyclicBarrier
, если у потока есть проблема (время ожидания, прервано ...), все остальные, которые достигли,await()
получают исключение. Смотрите Javadoc:источник
Я думаю, что JavaDoc объяснил различия явно. Большинство людей знают, что CountDownLatch не может быть сброшен, однако CyclicBarrier может. Но это не единственное отличие, иначе CyclicBarrier можно переименовать в ResetbleCountDownLatch. Мы должны рассказать о различиях с точки зрения их целей, которые описаны в JavaDoc.
CountDownLatch: средство синхронизации, позволяющее одному или нескольким потокам дождаться завершения набора операций, выполняемых в других потоках.
CyclicBarrier: средство синхронизации, позволяющее всем потокам ожидать друг друга, чтобы достичь общей барьерной точки.
В countDownLatch есть один или несколько потоков, ожидающих завершения набора других потоков . В этой ситуации существует два типа потоков: один тип ожидает, другой тип что-то делает, после завершения своих задач они могут ожидать или просто завершиться.
В CyclicBarrier есть только один тип потоков, они ждут друг друга, они равны.
источник
Основное отличие задокументировано прямо в Javadocs для CountdownLatch. А именно:
Источник 1.6 Javadoc
источник
CountDownLatch используется для одноразовой синхронизации. При использовании CountDownLatch любой поток может вызывать countDown () столько раз, сколько пожелает. Потоки, вызвавшие await (), блокируются до тех пор, пока счетчик не достигнет нуля из-за вызовов countDown () другими неблокированными потоками. Javadoc для CountDownLatch состояний:
Напротив, циклический барьер используется для нескольких точек синхронизации, например, если набор потоков выполняет циклическое / поэтапное вычисление и нуждается в синхронизации перед началом следующей итерации / фазы. Согласно javadoc для CyclicBarrier :
В отличие от CountDownLatch, каждый вызов await () относится к некоторой фазе и может привести к блокировке потока, пока все стороны, принадлежащие этой фазе, не вызовут await (). Нет явной операции countDown (), поддерживаемой CyclicBarrier.
источник
На этот вопрос уже дан адекватный ответ, но я думаю, что могу немного добавить ценность, опубликовав некоторый код.
Чтобы проиллюстрировать поведение циклического барьера, я сделал несколько примеров кода. Как только барьер опрокидывается, он автоматически сбрасывается, чтобы его можно было использовать снова (следовательно, он является «циклическим»). Когда вы запускаете программу, обратите внимание, что распечатки «Let's play» запускаются только после того, как барьер опрокинут.
источник
Когда я изучал защелки и циклические барьеры, я придумал эту метафору. Циклические барьеры . Представьте, что в компании есть комната для переговоров. Чтобы начать собрание, на собрание должно прийти определенное количество участников (чтобы сделать его официальным). ниже приведен код обычного участника собрания (сотрудника)
сотрудник присоединяется к собранию, ждет, пока другие придут, чтобы начать собрание. кроме того, он выходит, если собрание отменяется :) тогда у нас есть БОСС, как дозы не любят ждать появления других, и если он теряет своего пациента, он отменяет собрание.
В обычный день сотрудник приходит на собрание, ожидая появления других, и если некоторые посетители не приходят, им приходится ждать бесконечно! на каком-то специальном собрании приходит начальник, и он не любит ждать. (5 человек должны начать совещание, но приходит только начальник, а также служащий с энтузиазмом), поэтому он отменяет собрание (сердито)
Вывод:
Существует еще один сценарий, в котором другой внешний поток (землетрясение) отменяет собрание (метод сброса вызова). в этом случае все ожидающие потоки просыпаются в результате исключения.
выполнение кода приведет к забавному выводу:
Вы также можете добавить секретаря в комнату для собраний, если она проводится, она регистрирует все, но не участвует в собрании:
Защелки : если злой начальник хочет провести выставку для клиентов компании, все должно быть готово (ресурсы). мы предоставляем список дел каждому рабочему (Thread), дозирующему его работу, и мы проверяем список дел (некоторые рабочие рисуют, другие готовят звуковую систему ...). Когда все пункты в списке дел завершены (ресурсы предоставлены), мы можем открыть двери для клиентов.
А рабочие как готовят выставку
источник
В двух словах , просто чтобы понять ключевые функциональные различия между ними:
и
кроме, конечно, таких функций, как неблокирование, временное ожидание, диагностика и все, что было подробно описано в ответах выше.
Вышеупомянутые классы, однако, полностью функциональны и эквивалентны, в пределах предоставленной функциональности, их соответствующим однофамильцам.
С другой стороны,
CountDownLatch
внутренние классы являются подклассамиAQS
, хотя иCyclicBarrier
используютReentrantLock
(я подозреваю, что это может быть другой путь, или оба могут использовать AQS или оба используют Lock - без потери эффективности производительности)источник
Одно очевидное отличие состоит в том, что только N потоков могут ожидать на циклическом барьере N освобождение за один цикл. Но неограниченное количество потоков может ожидать в CountDownLatch из N. Уменьшение обратного отсчета может быть выполнено одним потоком N раз или N потоками по одному разу или в каждой комбинации.
источник
В случае CyclicBarrier, как только ВСЕ дочерние потоки начинают вызывать барьер .await (), Runnable выполняется в Барьере. Для завершения барьера.await в каждом дочернем потоке требуется разное время, и все они завершаются в одно и то же время.
источник
В CountDownLatch основные потоки ожидают завершения других потоков. В CyclicBarrier рабочие потоки ждут друг друга для завершения своего выполнения.
Вы не можете повторно использовать один и тот же экземпляр CountDownLatch, когда счетчик достигает нуля и защелка открыта, с другой стороны, CyclicBarrier может быть повторно использован путем сброса барьера, как только барьер сломан.
источник
CountDownLatch - это обратный отсчет чего угодно; CyclicBarrier обратный отсчет только для потока
Предположим, что есть 5 рабочих нитей и одна нить грузоотправителя, а когда рабочие изготовят 100 изделий, грузоотправитель отправит их.
Для CountDownLatch счетчик может быть на рабочих или предметах
Для CyclicBarrier счетчик может только на рабочих
Если рабочий засыпает бесконечно, с CountDownLatch на предметах, Грузоотправитель может отправить; Тем не менее, с CyclicBarrier, Shipper никогда не может быть вызван
источник
@Kevin Lee и @Jon Я попробовал CyclicBarrier с опциональным Runnable. Похоже, что он запускается в начале и после чаевых CyclicBarrier. Вот код и вывод
статический барьер CyclicBarrier;
Вывод
источник