Блокирующие замки против неблокирующих замков

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

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

while (true) {if (checkAndGetTheLock ()) break; }

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

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

 chrisapotek27 февр. 2012 г., 18:42
@JB Низет: Я думаю, что вы должны принять это решение самостоятельно, используя синхронизированный против ReentrantLock.
 JB Nizet27 февр. 2012 г., 18:39
AFAIK, JVM делает эту оптимизацию для вас, если нет конфликта на блокировку (что должно быть в случае быстрой операции)
 usr27 февр. 2012 г., 18:37
Сколько операций блокировки вы будете выполнять на ядро процессора в секунду?

Ответы на вопрос(2)

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

 usr27 февр. 2012 г., 18:42
Этот ответ является правильным и не должен быть опущен.
 usr27 февр. 2012 г., 19:59
Я проголосовал за это. Есть отмена понижения.
 Martin James27 февр. 2012 г., 19:58
@usr хорошо, почему ты тогда не проголосовал? Мне очень хотелось дважды это понизить, но это было бы несправедливо по отношению к М. Платвоэту.
 Martin James27 февр. 2012 г., 20:11
@usr - в этом случае я тоже добавлю upvote, потому что это единственный способ быть уверенным. Тестирование важно, но до того, как разработчик достигнет этой стадии, есть несколько проектов, которые определенно приведут к ужасной производительности, никаких предположений не требуется. Не использовать их - вопрос обучения / опыта.
Решение Вопроса

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

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

А также (что, IMO, самый важный момент):

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

 chrisapotek27 февр. 2012 г., 19:21
Я бы не стал верить, что «некоторые JVM выбирают между двумя адаптивно, основываясь на данных профилирования прошлого времени ожидания, но большинство просто приостанавливают потоки, ожидающие блокировки». Но вы никогда не узнаете, на что способны эти современные виртуальные машины JSM. Я думаю, что синхронизированные блокирует, а ReentrantLock занят ожидания. Но если они могут превращаться друг в друга во время выполнения, я не уверен.
 JB Nizet27 февр. 2012 г., 19:29
Где вы читали, что ReentrantLock занят ожиданием? Если бы это было так, это поставило бы JVM на колени для долгого ожидания. Javadoc говорит:Блокировка взаимного исключения с повторным входом с тем же базовым поведением и семантикой, что и для неявной блокировки монитора, доступ к которой осуществляется с помощью синхронизированных методов и операторов, но с расширенными возможностями.
 chrisapotek28 февр. 2012 г., 08:52
Так что, если я хочу использовать занятую блокировку ожидания, я должен сделать это сам, используя атомарные примитивы, верно?
 chrisapotek27 февр. 2012 г., 20:54
Я могу ошибаться, но, просматривая исходный код, я подумал, что это его подход:fuseyism.com/classpath/doc/java/util/concurrent/locks/... Нееет! JVM НЕ использует ReentrantLock для своих внутренних вещей.
 John Vint27 февр. 2012 г., 23:11
@chrisapotek ReentrantLock построен с использованием AbstractQueuedSynchronizer в качестве механизма синхронизации. Другими словами, ReentrantLock использует AbstractQueuedSynchronizer для приостановки и пробуждения потоков. Но, как отметил JB Nizet, ReentrantLock - абсолютно блокирующая конструкция.

Ваш ответ на вопрос