2014-01-13 5 views
4

Я вижу, что ReentrantLock примерно на 50% быстрее, чем synchronized и AtomicInteger 100% быстрее. Почему такая разница с временем выполнения этих трех методов синхронизации: synchronized, ReentrantLock и AtomicInteger (или какой-либо класс из пакета Atomic).синхронизированный vs ReentrantLock vs AtomicInteger время выполнения

Есть ли другие популярные и расширенные методы синхронизации в стороне от этих?

+3

Как именно вы получили эти номера производительности? Microbenchmarking на Java очень сложно из-за JIT и GC. Вы можете легко получить вводящие в заблуждение результаты. – Jesper

+0

Я думаю, вы имеете в виду 'java.util.concurrent' –

+0

Я просто использую 'System.nanoTime()', это не исчерпывающий тест, и проценты, которые я дал, были лишь показательными. – dabadaba

ответ

5

AtomicInteger намного быстрее, чем два других метода синхронизации на вашем оборудовании, поскольку он не блокируется. На архитектурах, где ЦП обеспечивает базовые возможности для блокировки без параллелизма, операции AtomicInteger выполняются полностью на аппаратном уровне, причем критически важная команда обычно принимает одну команду ЦП. Напротив, ReentrantLock и synchronized используют несколько инструкций для выполнения своей задачи, поэтому вы видите некоторые значительные накладные расходы, связанные с ними.

+0

Что означает блокировка? – dabadaba

+0

@dabadaba Это означает, что операции над 'AtomicInteger' не будут блокировать другие потоки в течение неопределенных временных интервалов, позволяя вашим потокам как группе всегда делать некоторый прогресс. – dasblinkenlight

+0

Значит, более или менее это означает, что он не работает вместе с другими потоками, но на другом уровне, на аппаратном уровне? – dabadaba

9

Некоторые факторы влияют на это.

  • версия Java. Java 5.0 был намного быстрее для ReentrantLock, Java 7 не так много
  • уровень раздора. синхронизированные работы лучше всего (как и блокировка вообще) с низкими конкурирующими ставками. ReentrantLock работает лучше с более высокими конкурирующими ставками. YMWV
  • сколько оптимизация может сделать JIT. Оптимизация JIT синхронизируется способами ReentrantLOck. Если это невозможно, вы не увидите преимущества.
  • синхронизированный GC в своих действиях. ReentrantLock может создавать мусор, который может замедлить работу и запускать GC в зависимости от того, как он используется.

AtomicInteger использует те же примитивы, которые используют блокировку, но ожидают ожидание. CompareAndSet также называется CompareAndSwap, то есть намного проще в том, что он делает (и гораздо более ограниченным)

Коллекции ConcurrentXxxx, CopyOnWriteArrayXxxx очень популярны. Они обеспечивают параллелизм без необходимости использования блокировки напрямую (и в некоторых случаях вообще никаких блокировок)

+0

Что вы имеете в виду с утверждением? Ваш ответ соответствует тому, что ReentrantLock работает медленнее, чем синхронизирован, и я увидел противоположное в своих результатах, снова проверьте мой пост. Или, может быть, я не понимаю вашего ответа. – dabadaba

+0

@ dabadaba да когда-то ReentrantLock быстрее, а иногда и медленнее. Все зависит от таких факторов, как перечисленные выше. Даже ваша архитектура процессора может иметь значение. Я видел пример, когда один и тот же код с тем же JVM запуском на разных моделях CPU (на ПК другой ноутбук) получил значительно разные результаты, относительно которых быстрее. –

+0

@dabadaba contention означает, сколько процессоров пытается использовать один и тот же ресурс одновременно. Попробуйте свои тесты только с одним потоком на ресурс. –

1

Я думаю, что вы делаете общую ошибку, оценивая эти 3 элемента для сравнения.

В основном, когда ReentrantLock позволяет повысить гибкость при синхронизации блоков по сравнению с синхронизированным ключом. Atomic - это то, что использует другой подход, основанный на CAS (Compare and Swap) для управления обновлениями в параллельном контексте.

Предлагаю вам прочитать глубокую библию параллелизма для платформы Java.

Java Concurrency in Practice - Brian Göetz, Tim Peierls, Joshua Bloch, Joseph Bowbeer, David Holmes & Doug Lea

Там разница много в наличии глубоких знаний о параллельности и знать, что язык может предложить вам решение проблемы параллелизма и воспользовавшись многопоточности.

Что касается производительности, это зависит от текущего сценария.

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