1. синхронизированный
До JDK 1.6 синхронизация была тяжеловесной блокировкой и была неэффективной.
Начиная с JDK 1.6, синхронизированный сделал много оптимизаций, таких как смещенные блокировки, облегченные блокировки, спин-блокировки, адаптивные спин-блокировки, устранение блокировок, огрубление блокировок и другие технологии для уменьшения накладных расходов на операции блокировок.
Синхронизированная блокировка синхронизации содержит четыре состояния: отсутствие блокировки, смещенная блокировка, облегченная блокировка и усиленная блокировка, которые будут постепенно обостряться по мере конкуренции. Синхронизированные блокировки синхронизации могут быть обновлены, но не понижены, чтобы повысить эффективность получения и освобождения блокировок.
Основной принцип синхронизации
синхронизированный декорированный кодовый блок
Декомпилировав файл .class, можно получить, посмотрев на байт-код: в блоке кода используетсяmonitorenterиmonitorexitинструкция, котораяmonitorenterИнструкция указывает на начало блока синхронизированного кода,monitorexitДиректива указывает, где заканчивается синхронизированный блок кода.
синхронизированный модифицированный метод
Так же посмотрев байткод можно получить: в методе синхронизации будет содержатьсяACC_SYNCHRONIZEDмаркер. Этот маркер указывает, что метод является синхронизированным и, таким образом, выполняет соответствующий синхронизированный вызов.
2. Блокировка объекта, блокировка класса, частная блокировка
блокировка объекта: украшен синхронизированнымнестатическийБлокировки, используемые методом synchronized(this) и синхронизированными блоками кода, являются объектными блокировками.
блокировка класса: украшен синхронизированнымстатическийБлокировки, используемые методом synchronized(class), а также блоки synchronized(class) синхронизированного кода, являются блокировками класса.
частный замок: объявить частное свойство, такое как блокировка частного объекта внутри класса, и использовать синхронизированный (блокировка) в синхронизированном блоке, который необходимо заблокировать.
Их характеристики:
- Блокировки объектов являются реентерабельными.
- Когда поток получает объектную блокировку объекта, поток по-прежнему может вызывать любой другой синхронизированный метод или синхронизированный (этот) синхронизированный блок кода, требующий блокировки объекта.
- Когда поток обращается к блоку синхронизированного (этого) синхронизированного кода объекта, доступ других потоков ко всем другим блокам синхронизированного (этого) синхронизированного кода в этом объекте будет заблокирован, поскольку доступ осуществляется к той же блокировке объекта.
- Для каждого класса существует только одна блокировка класса, но классы могут быть созданы как объекты, поэтому каждый объект соответствует блокировке объекта.
- Блокировки классов и блокировки объектов не конкурируют друг с другом.
- Частные блокировки и блокировки объектов также не конкурируют между собой.
- Использование приватных блокировок может уменьшить степень детализации блокировок и уменьшить накладные расходы, вызванные блокировками.
Механизм ожидания/уведомления, реализованный приватными блокировками:
Object lock = new Object();
// 由等待方线程实现
synchronized (lock) {
while (条件不满足) {
lock.wait();
}
}
// 由通知方线程实现
synchronized (lock) {
条件发生改变
lock.notify();
}
3. Блокировка повторного входа
ReentrantLock — это эксклюзивная/эксклюзивная блокировка. По сравнению с синхронизированным он более гибкий. Но процесс блокировки и разблокировки нужно написать самому. Его гибкость заключается в его многочисленных характеристиках.
ReentrantLock должен явно снять блокировку. Особенно, когда программа ненормальна, синхронизированный автоматически снимает блокировку, а ReentrantLock не снимает блокировку автоматически, поэтому блокировку необходимо снять окончательно.
Его особенности:
- справедливость: Поддерживает честные и нечестные блокировки. Несправедливые блокировки используются по умолчанию.
- возвращающийся
- прерываемый: по сравнению с синхронизированной, это прерываемая блокировка, которая может реагировать на прерывания.
- механизм тайм-аута: Блокировка не может быть получена после истечения времени ожидания, поэтому она не вызовет взаимоблокировки.
ReentrantLock является основой многих классов, например, сегмент, используемый внутри ConcurrentHashMap, наследует ReentrantLock, а CopyOnWriteArrayList также использует ReentrantLock.
4. РеентерабельныйReadWriteLock
Я написал статью раньше«ReentrantReadWriteLock и его использование в RxCache»Подробно представлен ReentrantReadWriteLock.
Он имеет блокировку чтения (ReadLock) и блокировку записи (WriteLock), блокировка чтения — это общая блокировка, а блокировка записи — эксклюзивная блокировка.
Его особенности:
- справедливость: Поддерживает честные и нечестные блокировки. Несправедливые блокировки используются по умолчанию.
- возвращающийся: Поток чтения может снова получить блокировку чтения после получения блокировки чтения. Поток записи может снова получить блокировку записи после получения блокировки записи, а также может получить блокировку чтения (ухудшение блокировки).
- заблокировать понижение версии: Процесс получения блокировки записи, затем получения блокировки чтения и снятия блокировки записи. Блокировка понижения предназначена для обеспечения видимости данных.
5. КАС
Упомянутые выше ReentrantLock и ReentrantReadWriteLock основаны на AbstractQueuedSynchronizer (AQS), а AQS основан на CAS. Полное название CAS — Compare And Swap, алгоритм без блокировки.
И синхронизация, и блокировка используют механизм пессимистической блокировки, тогда как CAS является реализацией оптимистичной блокировки.
Особенности КАС:
- Реализовано путем вызова кода JNI
- неблокирующий алгоритм
- Инклюзивная блокировка
Проблемы с КАС:
- ABA
- Длительное время цикла и высокие накладные расходы
- Только гарантированные атомарные операции над общей переменной
6. Состояние
Условие используется для замены традиционных функций wait() и notify() для достижения взаимодействия между потоками.
В объекте Condition методы wait, notify и notifyAll соответствуют await, signal и signalAll соответственно.
Условие должно использоваться с замком, а экземпляр условия должен быть привязан к замку.
Его особенности:
- Объект Lock может создавать несколько экземпляров Condition, поэтому он может поддерживать несколько очередей ожидания.
- При использовании методов await, signal или signalAll условие сначала должно получить блокировку() блокировки.
- Поддержка реагирования на прерывания
- Поддерживается функция пробуждения по времени
7. Семафор
Semaphore, CountDownLatch, CyclicBarrier — все это параллельные классы инструментов.
Семафор может указать несколько потоков для одновременного доступа к ресурсу, в то время как синхронизация и ReentrantLock позволяют только одному потоку обращаться к ресурсу за раз. Поскольку семафор подходит для ограничения количества потоков, обращающихся к определенным ресурсам, его можно использовать для ограничения тока.
Semaphore не реализует синхронизацию данных, а синхронизацию данных все равно нужно реализовать с помощью synchronized, Lock и т. д.
Его особенности:
- Режим совместного доступа на основе AQS
- Справедливость: поддерживает честные и несправедливые режимы. Нечестный режим используется по умолчанию.
8. Защелка обратного отсчета
CountDownLatch можно рассматривать как счетчик обратного отсчета, который позволяет одному или нескольким потокам ожидать завершения операций другими потоками. Следовательно, CountDownLatch — это общая блокировка.
Метод countDown() класса CountDownLatch уменьшает счетчик на 1, а метод await() блокирует текущий поток до тех пор, пока счетчик не достигнет 0.
в моей структуре сканераNetDiscoveryCountDownLatch используется для управления приостановкой и возобновлением работы сканера.
9. Классификация замков
Х. Резюме
В этой статье кратко описаны некоторые часто используемые блокировки в Java и некоторые их характеристики.Освоение этих блокировок является основой для освоения параллельного программирования в Java. Конечно, блокировки Java не ограничиваются этим, например блокировка сегмента ConcurrentHashMap (сегмент), распределенная блокировка, используемая в распределенной среде.
Использованная литература:
- Искусство параллельного программирования на Java
- «Практика параллельного программирования на Java»
- Java-блокировка, о которой нужно сказать
Стек технологий Java и Android: еженедельно обновляйте и публикуйте оригинальные технические статьи, добро пожаловать, чтобы отсканировать QR-код общедоступной учетной записи ниже и подписаться, и с нетерпением ждем роста и развития вместе с вами.