2012-02-27 4 views
5

Я думаю здесь: Если у вас есть 2 потока, выполняющих операции FAST, которые необходимо синхронизировать, не является ли неблокирующий подход быстрее/лучше, чем подход блокировки/контекстного переключения?Блокирующие блокировки и блокирующие блокировки

По неблокирующая я имею в виду что-то вроде:

время (правда) { если (checkAndGetTheLock)() перерыв; }

Единственное, что я могу придумать, это голодание (с выгоранием процессора), если у вас слишком много потоков, связанных вокруг блокировки.

Как сбалансировать один подход по сравнению с другим?

+0

Сколько операций блокировки вы будете выполнять за процессор в секунду? – usr

+0

AFAIK, JVM делает эту оптимизацию для вас, если нет конкуренции на блокировке (что должно быть, если операция выполняется быстро) –

+0

@JB Nizet: Думаю, вам нужно принять это решение самостоятельно, используя синхронизированный или ReentrantLock. – chrisapotek

ответ

5

Вот что Java Параллелизм на практике говорит о предмете:

Виртуальная машина Java может реализовать блокирование либо с помощью спин-ожидания (неоднократно пытается получить блокировку, пока не удастся) или bysuspending заблокирован поток через операционную систему. Что более эффективно зависит от взаимосвязи между служебными данными коммутатора контекста и , пока блокировка не станет доступной; предпочтительным является ожидание вращения для короткие ожидания и подвеска предпочтительны для длительных ожиданий. Некоторые JVM выбирают между двумя адаптивными на основе данных профилирования прошлых ожиданий раз, но большинство просто приостанавливает потоки, ожидая блокировки.

А также (что, ИМО, самое главное):

Не беспокойтесь чрезмерно о стоимости uncontended синхронизации. Базовый механизм уже довольно быстрый, и JVM могут выполнять дополнительные оптимизации, которые дополнительно уменьшают или устраняют стоимость. Вместо этого, усилия по оптимизации фокусировки в областях, где происходит конфликт блокировок .

+0

Я бы не верил, что «некоторые JVM выбирают между двумя адаптивными на основе профилирующих данных прошлых времен ожидания, но большинство просто приостанавливает потоки, ожидая блокировки». Но вы никогда не узнаете, на что способны эти современные JVM Hotspot. Я бы подумал, что синхронизация блокируется, а ReentrantLock занят. Но если они могут меняться друг в друге во время выполнения, я не уверен. – chrisapotek

+1

Где вы читаете, что ReentrantLock оживлен? Если бы это произошло, это привело бы JVM на колени на долгие ожидания. Javadoc говорит: * Повторное взаимное исключение Lock с тем же основным поведением и семантикой, что и неявная блокировка монитора, с помощью синхронизированных методов и операторов, но с расширенными возможностями. * –

+0

Я могу ошибаться, но, просматривая исходный код, я думал, что это был его подход: http://fuseyism.com/classpath/doc/java/util/concurrent/locks/AbstractQueuedSynchronizer-source.html NOOOOO! JVM НЕ использует ReentrantLock для своих внутренних вещей. – chrisapotek

1

Ну, единственный способ убедиться в этом - это проверить его. Когда дело доходит до многопоточности и производительности, вы просто не можете предположить.

+0

Этот ответ правильный и его нельзя отбрасывать. – usr

+0

@usr хорошо, почему вы тогда не подняли его? Я был сильно склонен к тому, чтобы дважды его удвоить, но это было бы несправедливо на M Platvoet. –

+0

Я поддержал его. Существует аннулирование downvote. – usr

Смежные вопросы