В предыдущих статьях мы представили слишком много основных принципов, технологий и новых концепций, поэтому в этой статье давайте не будем спешить и узнаем о трех классах инструментов фреймворка, основанных на этих базовых принципах, в параллельных пакетах Java.
они соответственно:
- семафор
- Защелка обратного отсчета
- Барьер ЦиклическийБарьер
Поэтому, поскольку это класс инструментов, он должен быть неотделим от конкретной сцены, поэтому нет никого, кто лучше или хуже друг друга, есть только тот, кто больше подходит.
семафор
Для каких сценариев использования подходит Semaphore?Возьмем общий пример:
Если сейчас есть парковка, то на ней всего десять парковочных мест, а когда все десять парковочных мест заняты, машинам снаружи не разрешается въезжать, и они должны ждать снаружи. Въезд разрешен только одной машине
Этот сценарий отличается от нашего общего сценария параллелизма.Вообще говоря, наши критические ресурсы могут быть доступны только одному потоку, а другие потоки ждут.
Однако существует сценарий, в котором критические ресурсы разрешают одновременный доступ к нескольким потокам, а потоки, превышающие лимит, блокируются и ожидаются.
Такого рода ситуации также можно достичь с помощью исходного набора, но это называется «строительными колесами», а среда параллелизма Java предоставляет нам класс инструментов, специально подходящий для этого сценария.
Можно сказать, что семафор является классом инструментов для описанного выше сценария.Давайте напишем демонстрацию для реализации приведенной выше логики:
После выполнения программы вы увидите:
Видите ли, разрешен вход только одному потоку, это Semaphore.
Внутренний принцип семафора на самом деле заключается в том, что когда вы посмотрите на исходный код, вы обнаружите, что реализация ReentrantLock очень похожа на реализацию нашего ReentrantLock, включая поддержку справедливых и нечестных политик, но состояние в AQS обычно меньше, чем у нашего ReentrantLock. или равно единице в первой реализации (если только не повторные блокировки), а состояние последней меньше или равно десяти, записывая количество оставшихся доступных критических ресурсов.
Итак, с семафором связана неотъемлемая проблема: если поток повторно входит в критическую секцию, нужно ли уменьшать количество доступных критических ресурсов?
Всего на стоянке десять парковочных мест.Одна машина въехала и заняла парковочное место.По прошествии некоторого времени об этом сообщили администратору,и я бы тоже заняла парковочное место.Админ согласится?
Фактически в глазах администратора Java поток, вошедший в критическую секцию, является «Мастером», и требования будут удовлетворены первыми, даже если занятые им ресурсы не будут освобождены.
Следовательно, в механизме семафоров поток может занять все критические ресурсы после входа в критическую секцию.
Защелка обратного отсчета
Давайте посмотрим на этот CountDownLatch. Название звучит очень продвинуто. Какие функции он предоставляет?
Есть такой распространенный сценарий, давайте посмотрим:
Люди часто используют Pinduoduo каждый день. Чтобы товар доставили, нужно, чтобы к группе присоединились как минимум два-три человека.
Здесь мы не будем изучать его бизнес-модель, независимо от того, как она достигает прибыльности, просто такой сценарий, если вы хотите реализовать его с помощью базового параллельного API, вы можете придумать:
Подойди к потоку, чтобы заблокировать один раз, пока не будет достигнуто указанное число, все просыпаются
Да, верно, CountDownLatch реализован так внутри, колесо было построено для вас, давайте посмотрим, как реализовать приведенный выше модельный случай:
Запустите его еще несколько раз, и вы обнаружите, что результат правильный.Порядок людей, которые присоединяются к группе, может быть другим, но продавец доставит товар только после того, как все три человека будут готовы.
Кроме того, у него есть еще множество применений, например, в забеге на 100 метров, где судья дает свисток только тогда, когда все спортсмены готовы, и так далее.
Принцип реализации в принципе аналогичен явной блокировке.Разница еще в контроле состояния.CountDownLatch только определяет равно ли состояние нулю.Если оно не равно нулю,значит время еще не пришло и блокирует текущий поток.
Каждый вызов метода countDown будет уменьшать ресурс обратного отсчета на единицу и пробуждать заблокированный поток, пока он не достигнет нуля.
циклическийбарьер
CyclicBarrier на самом деле очень похож на CountDownLatch, мы сначала представим CyclicBarrier, а затем сравним и сравним их различия и сходства с вами.
Рассмотрим такой сценарий:
Квартирный шаттл всегда отправляется и едет к станции метро после того, как заполнит машину внизу квартиры, а затем возвращается, чтобы забрать следующую группу людей.
В таком сценарии рассмотрим, как реализовать:
Эффект наверное такой:
CyclicBarrier похож на барьер. При создании его экземпляра вам необходимо передать два параметра. Первый параметр указывает, сколько потоков наш барьер перехватывает не более чем до открытия барьера. Второй параметр указывает, что последний поток, достигший барьера, должен выполнить дополнительные действия. , действовать.
В общем, после того, как последний поток достигнет барьера, барьер будет открыт, все предыдущие потоки будут освобождены, а в конце барьер снова закроется.
CyclicBarrier нужен только один await для выполнения всех функций.Подытожим логику реализации этого метода:
- Во-первых, уменьшите количество ресурсов, доступных одновременно
- Если количество доступных ресурсов равно нулю, это означает, что это последний поток, поэтому он выполнит дополнительную операцию, которую мы передали, разбудит все прибывшие и ожидающие потоки и перезапустит счетчик барьеров.
- В противном случае это означает, что это не последний поток, поэтому он блокирует свой собственный поток в условной очереди в цикле.
Что ж, прочитав CyclicBarrier, вы обнаружите, что он действительно похож на нашу защелку обратного отсчета.Поясним разницу и связь между ними.
первая разница
Как только защелка обратного отсчета CountDownLatch открыта, ее нельзя закрыть снова, а это значит, что пока countDown вызывается достаточное количество раз, метод await станет недействительным, и он является одноразовым.
CyclicBarrier происходит в цикле, когда последний поток достигает барьера, счетчик барьера будет сброшен первым, и барьер снова откроет барьер перехвата.
второе отличие
CountDownLatch - это счетчик, и один поток записывается как один. В течение этого периода поток не блокируется. При достижении указанного числа внешний ожидающий поток будет разбужен. То есть существует один или несколько внешних потоки, ожидающие выполнения условия, прежде чем продолжить выполнение. , и это условие должно удовлетворить определенное количество потоков, чтобы активировать продолжение выполнения текущего внешнего потока.
CyclicBarrier подобен забору, один поток блокирует один, пока не будет заблокировано указанное количество потоков, все они активируются одновременно, что позволяет выполнять их одновременно, как 100-метровый спринт.
последний из последних
Выше приведены три класса инструментов, которые проще использовать в нашем параллельном пакете Java.Основная реализация первых двух почти полностью опирается на принцип и метод явных блокировок, а последний — на использование явных блокировок и условий. переменные для воссоздания Колеса — очень полезный инструмент!
В дополнение к этому, еще одна вещь, которую нужно сказать, это то, что мы уже представили основные основные вещи во всем параллелизме, всего 14 статей, от основных концепций потоков до принципов блокировки, пулов потоков и асинхронной задачи. думаю, что резюме достаточно подробно, как много вы знаете?
Неважно, если вы не помните, я также предоставлю вам краткое изложение интеллект-карты, в которой перечислено вышеуказанное основное содержание, с которым вы можете ознакомиться, и вы также можете написать мне в личном сообщении для обсуждения и изучения. .
Как получить: ответьте на «Concurrent» в официальном аккаунте или загрузите прямо с моего Github.
ps: У меня тоже праздник. Желаю всем счастливого Нового года. Во время Праздника Весны мы не будем обновлять текст. После праздника мы откроем новую главу. В системе обобщены технологии и принципы, связанные с " базу данных". Обратите внимание!
Обратите внимание на публику и не теряйтесь, программист, который любит делиться. Официальный аккаунт отвечает на "1024" и добавляет авторский WeChat для обсуждения и изучения вместе! Все материалы кода кейса, использованные в каждой статье, будут загружены на мой личный github. GitHub.com/один батат/о… Добро пожаловать!