Блокировки как инструмент для одновременного обмена данными и обеспечения согласованности имеют несколько реализаций на платформе JAVA (например, Synchronized, ReentrantLock и т. д.). Эти уже написанные блокировки обеспечивают удобство для нашей разработки, но конкретная природа и тип блокировок редко упоминаются. В этой серии статей будут проанализированы распространенные имена и характеристики блокировок в JAVA, чтобы ответить на ваши вопросы.
блокирующий замок
Блокирующие блокировки, в отличие от спин-блокировок, изменяют рабочее состояние потока.
В среде JAVA поток Thread имеет следующие состояния:
1. Новое государство
2. Готовое состояние
3. Текущий статус
4. Заблокированное состояние
5. Состояние смерти
Можно сказать, что блокирующая блокировка позволяет потоку войти в состояние блокировки и ждать. Когда получен соответствующий сигнал (пробуждение, время), поток может перейти в состояние готовности. Все потоки в состоянии готовности переходят в состояние выполнения. посредством конкуренции.
В JAVA методы, которые могут входить/выходить, блокировать состояние или содержать блокирующие блокировки, включают ключевое слово Synchronized (среди них блокировка веса), ReentrantLock, Object.wait()/notify(), LockSupport.park()/unpart()( сок часто используется)
Ниже приведен пример блокирующей блокировки JAVA:
блокировка пакета; импорт java.util.concurrent.atomic.AtomicReferenceFieldUpdater; импорт java.util.concurrent.locks.LockSupport; общедоступный класс CLHLock1 { общедоступный статический класс CLHNode { частный изменчивый поток isLocked } @SuppressWarnings («неиспользуемый») частный изменчивый CLHNode; хвост частный статический окончательный ThreadLocal<CLHNode> LOCAL = новый; ThreadLocal<CLHNode>(); частный статический финал AtomicReferenceFieldUpdater<CLHLock1, CLHNode> UPDATER = AtomicReferenceFieldUpdater.newUpdater(CLHLock1.class, CLHNode.class, "tail"); public void lock() { CLHNode node = new CLHNode(); .set(узел); preNode = UPDATER.getAndSet(this, node); if (preNode!= null) {preNode.isLocked = Thread.currentThread(); LockSupport.park(this); preNode = null; LOCAL.set(node) } void unlock() { CLHNode node = LOCAL.get(); if (!UPDATER.compareAndSet(this, node, null)) { System.out.println("unlock/t" + node.isLocked.getName()); LockSupport.unpark(node.isLocked } node = null }}
Здесь мы используем блокирующую блокировку LockSupport.unpark(). Этот пример является модификацией блокировки CLH.
Преимущество блокировки блокировок заключается в том, что заблокированные потоки не занимают время процессора и не вызывают чрезмерной загрузки процессора, но время входа и время восстановления немного медленнее, чем у спин-блокировок.
В случае жесткой конкуренции производительность блокирующих локов существенно выше, чем у спин-локов.
Идеальная ситуация такова: используйте блокировки вращения, когда конкуренция между потоками не является жесткой, и блокировку блокировки, когда конкуренция жесткая.
(Полный текст заканчивается)