Смешивание синхронизировалось () с ReentrantLock.lock ()

В Java сделать ReentrantLock.lock() и ReetrantLock.unlock() используйте тот же механизм блокировки как synchronized()?

Мое предположение является "Нет", но я надеюсь быть неправым.

Пример:

Предположите, что Поток 1 и Поток 2 у обоих есть доступ к:

ReentrantLock lock = new ReentrantLock();

Поток 1 выполнение:

synchronized (lock) {
    // blah
}

Поток 2 выполнения:

lock.lock();
try {
    // blah
}
finally {
    lock.unlock();
}

Предположите, что Поток 1 достигает своей части сначала, затем Поток 2, прежде чем Поток 1 будет закончен: Распараллелит 2, ожидают Потока 1 для отъезда synchronized() блок, или это будет идти вперед и работать?

15
задан James Jensen 24 May 2010 в 23:38
поделиться

2 ответа

Нет, поток 2 может lock() даже если поток 1 синхронизирован на том же lock. Вот что говорится в документации:

Обратите внимание, что экземпляры Lock - это просто обычные объекты и сами могут быть использоваться в качестве цели в синхронизированном операторе. Приобретение блокировки монитора экземпляра Lock не имеет никакой определенной связи с вызовом любого из lock() этого экземпляра. Это рекомендуется, чтобы во избежание путаницы никогда не использовать экземпляры Lock таким образом кроме как в рамках их собственной реализации.

15
ответ дан 1 December 2019 в 03:04
поделиться

Эти два механизма различны. С точки зрения реализации / производительности:

  • синхронизированный механизм использует механизм блокировки, который «встроен» в JVM; базовый механизм зависит от конкретной реализации JVM, но обычно использует комбинацию необработанной инструкции операции сравнения и установки (CAS) для случаев, когда блокировка не оспаривается, плюс базовые механизмы блокировки, предоставляемые ОС;
  • классы блокировки, такие как ReentrantLock, в основном кодируются на чистой Java (с помощью библиотеки, представленной в Java 5, которая предоставляет инструкции CAS и планирование потоков для Java), поэтому они несколько более стандартизированы для ОС и более управляемы (см. ниже ).

В некоторых случаях явные блокировки могут работать лучше. Если вы посмотрите на это сравнение механизмов блокировки , которое я провел под Java 5, вы увидите, что в этом конкретном тесте (несколько потоков обращаются к массиву) явные классы блокировки, настроенные в «несправедливом» режиме (желтый и голубые треугольники) обеспечивают большую пропускную способность, чем обычная синхронизация (фиолетовые стрелки).

(Я должен также сказать, что производительность synchronized была улучшена в более поздних версиях Hotspot; в последних версиях или даже при других обстоятельствах этого может быть не так много - это, очевидно, один тест в одной среде. )

С точки зрения функциональности:

  • синхронизированный механизм обеспечивает минимальную функциональность (вы можете блокировать и разблокировать, блокировка - это операция по принципу «все или ничего», вы больше подчиняетесь алгоритму, выбранному разработчиками ОС), хотя с преимуществом встроенного синтаксиса и некоторого мониторинга, встроенного в JVM;
  • явные классы блокировки обеспечивают больший контроль, в частности, вы можете указать «справедливую» блокировку, блокировку с тайм-аутом, переопределить, если вам нужно изменить блокировку behiour ...
9
ответ дан 1 December 2019 в 03:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: