Подтвердить что ты не робот

Длинный примитив или AtomicLong для счетчика?

Мне нужен счетчик типа long со следующими требованиями/фактами:

  • Приращение счетчика должно занимать как можно меньше времени.
  • Счетчик будет записываться только одним потоком.
  • Чтение с счетчика будет выполнено в другом потоке.
  • Счетчик будет регулярно увеличиваться (до нескольких тысяч раз в секунду), но будет читаться только раз в пять секунд.
  • Точная точность не является существенной, только приблизительное представление о размере счетчика достаточно хорошее.
  • Счетчик никогда не очищается, уменьшается.

Основываясь на этих требованиях, как бы вы решили реализовать свой счетчик? Как простой long, как volatile long или используя AtomicLong? Почему?

На данный момент у меня есть volatile long, но мне было интересно, будет ли другой подход лучше. Я также увеличиваю свое время, выполняя ++counter, а не counter++. Действительно ли это действительно более эффективно (как меня верили в другое место), потому что не выполняются задания?

Заранее спасибо

Рич

4b9b3361

Ответ 1

Учитывая эти наборы требований, я думаю, что a volatile long должно быть достаточным. Счетчик не был бы неправильным с длиной не менее volatile, но читатель мог бы читать устаревшую информацию в этом случае.

Одна проблема заключается в том, что чтение и запись в long не требуется для атомарного, спецификация JVM, если она не объявлена ​​ volatile. Это означало бы, что поток чтения может получить довольно фиктивное значение, если он считывает значение, в то время как поток записи обновляет одну часть значения, но не другую.

Разница между ++counter и counter++, вероятно, не имеет значения, поскольку JVM поймет, что значение выражения больше не используется, а два эквивалентны в этом случае.

Ответ 2

В Java 8 используйте LongAdder, который даже лучше AtomicLong, где конфликт потоков высок.

LongAdder JavaDoc:

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

Ответ 3

какое время ожидания для вашей программы? Не могли бы вы поработать с нестабильным int и racy-reads?

Ответ 4

10 ^ 4 с шагом в секунду - 1 каждые 100 мкс. Эффективность - это не проблема, но атомарность может быть. У вас может быть 2 копии, и когда он будет прочитан, если они не равны, прочитайте снова.