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