Ich habe eine Bibliothek, die HTTP-Anrufe zu meinem Dienst macht. Ich habe versucht, den durchschnittlichen Durchschnitt meiner Dienste zu berechnen.Thread-sichere Methode zur Berechnung des gleitenden Durchschnitts
Hier ist die Kernlogik von, wie ich "laufenden Durchschnitt" errechne.
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);
}
}
Ist dieser Code thread sicher, weil dies von Multithread-Programm aufgerufen wird? Wenn nicht, wie kann ich das Multithread machen.
Ich möchte sicherstellen, dass diese Berechnung des laufenden Durchschnitts schnell ist, da diese Bibliothek unter sehr hoher Last läuft, so dass dies die Gesamtlatenz nicht erhöhen sollte. Auch ich bezweifle, ich brauche sogar BigDecimal
hier, double
oder long
könnte hier funktionieren.
Vom ArrayDeque API: „Sie sind nicht Thread-sicher, in der Abwesenheit von externer Synchronisation , sie unterstützen keinen gleichzeitigen Zugriff durch mehrere Threads. " Ich sehe dich extern nichts synchronisiert, also ... – azurefrog
Müssen Sie BigDecimal verwenden? Sieht so aus, als ob Sie für jeden 'movingAverage.add (...)' Aufruf drei BigDecimal-Objekte erstellen und zerstören. Wenn Sie 'long' und ein' long [] 'Array oder' double' und ein 'double []' Array verwenden könnten, würde es viel schneller gehen. –
@jameslarge Können Sie ein Beispiel geben, wie das mit 'long' oder' double' aussehen wird? – john