У меня есть библиотека, которая вызывает HTTP-запросы к моей службе. Я пытался подсчитать среднее значение времени, в течение которого мой сервис получает среднее значение.поток безопасный способ вычисления скользящего среднего
Вот основная логика того, как я рассчитываю «средний уровень».
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.LinkedList;
import java.util.Queue;
public class MovingAverage {
private final Queue<BigDecimal> window = new ArrayDeque<BigDecimal>();
private final int period;
private BigDecimal sum = BigDecimal.ZERO;
public MovingAverage(int period) {
this.period = period;
}
public void add(BigDecimal num) {
sum = sum.add(num);
window.add(num);
if (window.size() > period) {
sum = sum.subtract(window.remove());
}
}
public BigDecimal getAverage() {
if (window.isEmpty()) return BigDecimal.ZERO;
BigDecimal divisor = BigDecimal.valueOf(window.size());
return sum.divide(divisor, 2, RoundingMode.HALF_UP);
}
}
Этот код безопасен, потому что он вызывается из многопоточной программы? Если нет, то как я могу сделать это многопоточным.
Я хочу убедиться, что этот средний расчет выполняется быстро, поскольку эта библиотека работает под очень большой нагрузкой, поэтому это не должно увеличивать общую задержку. Также я сомневаюсь, что мне даже нужно использовать BigDecimal
здесь, double
или long
может работать здесь.
Из ArrayDeque API: «Они не поточно-, при отсутствии внешней синхронизации , они не поддерживают одновременный доступ несколькими потоками ». Я не вижу, чтобы вы внешне синхронизировали что-нибудь, поэтому ... – azurefrog
Вам нужно использовать BigDecimal? Похоже, вы создаете и уничтожаете три объекта BigDecimal для каждого вызова 'movingAverage.add (...)'. Если бы вы могли использовать 'long' и' long [] 'array или' double' и 'double []' array, то это было бы намного быстрее. –
@jameslarge Можете ли вы привести пример, как это будет выглядеть с 'long' или' double'? – john