Когда вы используете ключевое слово синхронизировано, мьютекс используется для обеспечения потокобезопасности и синхронного доступа к общим ресурсам. Для выполнения сложных параллельных задач часто требуется дальнейшее скоординированное выполнение между потоками. Например, режим ожидания/уведомления — это механизм скоординированного выполнения в многопоточной среде.
Получение и снятие блокировок через API (с использованием мьютекса) или вызов wait/notify и других методов — все это методы вызова низкого уровня. Далее необходимо создать абстракции более высокого уровня для синхронизации потоков. Обычно используемый вспомогательный класс синхронизации предназначен для дальнейшей инкапсуляции механизма активности синхронизации между двумя или более потоками. Его внутренний принцип заключается в достижении сложной координации между потоками с помощью существующего базового API.
Существует 5 вспомогательных классов синхронизации, подходящих для распространенных сценариев синхронизации:
1. Семафор Семафор — классический инструмент синхронизации. Семафоры часто используются для ограничения количества ресурсов (физических или логических), к которым поток может обращаться одновременно.
2.CountDownLatch — очень простой, но часто используемый вспомогательный класс синхронизации. Его цель — позволить одному или нескольким потокам блокироваться до тех пор, пока не будет завершен набор операций, выполняемых в других потоках.
3. CyclicBarrier — это сбрасываемая точка многосторонней синхронизации, которая полезна в некоторых сценариях параллельного программирования. Это позволяет группе потоков ждать друг друга, пока не будет достигнута общая точка барьера. CyclicBarrier полезен в программах, включающих набор потоков фиксированного размера, которые должны время от времени ждать друг друга. Поскольку барьер можно использовать повторно после освобождения ожидающего потока, он называется циклическим барьером.
4. Phaser — это многоразовый барьер синхронизации, который по функциям аналогичен CyclicBarrier и CountDownLatch, но более гибок в использовании. Он очень удобен для синхронной координации поэтапных вычислительных задач в многопоточной среде (когда требуется синхронизация между подзадачами в рамках Fork/Join, предпочтителен Phaser)
5. Exchanger позволяет двум потокам обмениваться объектами в определенной точке встречи, что более полезно в определенных конструкциях конвейеров. Exchanger предоставляет точку синхронизации, в которой пара потоков может обмениваться данными. Каждый поток предоставляет данные своему партнерскому потоку посредством входа в метод Exchange(), получает данные, предоставленные партнерским потоком, и возвращает их. Когда два потока обмениваются объектами через Exchanger, обмен безопасен для обоих потоков. Exchanger можно рассматривать как двунаправленную форму SynchronousQueue, которая более полезна в приложениях, включающих генетические алгоритмы и проектирование конвейеров.