В 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()
блок, или это будет идти вперед и работать?
Нет, поток 2 может lock()
даже если поток 1 синхронизирован
на том же lock
. Вот что говорится в документации:
Обратите внимание, что экземпляры Lock - это просто обычные объекты и сами могут быть использоваться в качестве цели в синхронизированном операторе. Приобретение блокировки монитора экземпляра Lock не имеет никакой определенной связи с вызовом любого из lock() этого экземпляра. Это рекомендуется, чтобы во избежание путаницы никогда не использовать экземпляры Lock таким образом кроме как в рамках их собственной реализации.
Эти два механизма различны. С точки зрения реализации / производительности:
В некоторых случаях явные блокировки могут работать лучше. Если вы посмотрите на это сравнение механизмов блокировки , которое я провел под Java 5, вы увидите, что в этом конкретном тесте (несколько потоков обращаются к массиву) явные классы блокировки, настроенные в «несправедливом» режиме (желтый и голубые треугольники) обеспечивают большую пропускную способность, чем обычная синхронизация (фиолетовые стрелки).
(Я должен также сказать, что производительность synchronized была улучшена в более поздних версиях Hotspot; в последних версиях или даже при других обстоятельствах этого может быть не так много - это, очевидно, один тест в одной среде. )
С точки зрения функциональности: