Я разрабатываю приложение, в котором мы имеем большое количество потоков и должны добавить 100 значений атомарно. Я использую AtomicLong
, которые хорошо работают, но все же нуждаются в улучшении производительности. Есть ли что-то, что дает лучшую производительность, чем AtomicLong?
Многопоточность суммирования большого количества значений атомарно
Ответ 1
Вы можете использовать LongAdder. LongAdder предлагает намного лучшую производительность, чем AtomicLong. Я бы посоветовал прочитать статью this, в которой автор опубликовал результаты сравнительного анализа и объяснил, что оставил много подробностей относительно производительности LongAdder. Но в двух словах LongAdder
extends Striped64
, который обрабатывает контент, прекращается, используя хеш-таблицу ячеек. Поэтому, когда 2 потока пытаются поставить какое-то значение, есть вероятность, что оба из них перестанут помещать значение в разные ячейки. Класс Cell использует Padding stratergy для уменьшения содержимого кэша ЦП. Более того, если вы посмотрите на исходный код, вы обнаружите, что класс ячейки использует CAS.
Операции Unsafe.compareAndSwap являются атомарными. Они берут указатель на кусок памяти (в данном случае состоящий из этого и valueOffset, который вместе укажите значение), значение сравнения и значение подкачки. Если JVM находит, что значение адресной памяти равно сравнению значение, то он сохраняет значение подкачки в адресной памяти и возвращает true. Это означает, что операции CAS бывают быстрыми и потоковыми безопасный способ обновления значения переменной и получения отзывов о том, операция была успешной или возникли разногласия.
Ответ 2
Раздел 15.3.2 JCIP:
при высоких уровнях конкуренции уровни, как правило, превосходят атомные переменных, но при более реалистичных уровнях конкуренции атомные переменные превосходят блокировки.
Вы можете либо попробовать схему возврата , чтобы улучшить производительность ваших атомных переменных, либо вы можете переключиться на использование полнофункционального ReentrantLock
s.