Я написал таймер, который будет измерять производительность конкретного кода в любом многопоточном приложении. В нижнем таймере он также заполнит карту тем, сколько звонков заняло х миллисекунд. Я буду использовать эту карту как часть моей гистограммы для дальнейшего анализа, как и какой процент звонков приняло это много миллисекунды и т.д.Потенциальное состояние гонки в классе таймера?
public static class StopWatch {
public static ConcurrentHashMap<Long, Long> histogram = new ConcurrentHashMap<Long, Long>();
public static StopWatch getInstance() {
return new StopWatch();
}
private long m_end = -1;
private long m_interval = -1;
private final long m_start;
private StopWatch() {
m_start = m_interval = currentTime();
}
public long getDuration() {
long result = 0;
final long startTime = m_start;
final long endTime = isStopWatchRunning() ? currentTime() : m_end;
result = convertNanoToMilliseconds(endTime - startTime);
boolean done = false;
while (!done) {
Long oldValue = histogram.putIfAbsent(result, 1L);
if (oldValue != null) {
done = histogram.replace(result, oldValue, oldValue + 1);
} else {
done = true;
}
}
return result;
}
public long getInterval() {
long result = 0;
final long startTime = m_interval;
final long endTime;
if (isStopWatchRunning()) {
endTime = m_interval = currentTime();
} else {
endTime = m_end;
}
result = convertNanoToMilliseconds(endTime - startTime);
return result;
}
public void stop() {
if (isStopWatchRunning()) {
m_end = currentTime();
}
}
private long currentTime() {
return System.nanoTime();
}
private boolean isStopWatchRunning() {
return (m_end <= 0);
}
private long convertNanoToMilliseconds(final long nanoseconds) {
return nanoseconds/1000000L;
}
}
Например, это путь, я буду использовать мой выше класс таймера для измерения выполнение конкретного кода в моем многопоточном приложении:
StopWatch timer = StopWatch.getInstance();
//... some code here to measure
timer.getDuration();
Теперь мой вопрос - Если вы посмотрите на методе getDuration
, я также заселять свою карту с информацией, например, сколько звонков приняли е миллисекунды, так что я может использовать эту карту позже для дальнейшего анализа, например, вычисления среднего, среднего, 95-го и 99-го процентиля. Является ли мой ниже код нить безопасной или есть какие-либо условия гонки?
boolean done = false;
while (!done) {
Long oldValue = histogram.putIfAbsent(result, 1L);
if (oldValue != null) {
done = histogram.replace(result, oldValue, oldValue + 1);
} else {
done = true;
}
}
Между вызовом Long oldValue = histogram.putIfAbsent(result, 1L);
и done = histogram.replace(result, oldValue, oldValue + 1);
значения в карте может измениться. Таким образом, oldValue
может быть устаревшим?
эта тема для HTTP: //codereview.stackexchange .com/ –
@AlexeiKaigorodov Только в том случае, если код работает по назначению, из которого OP не уверен. Сломанный код [off-topic] (http://codereview.stackexchange.com/help/on-topic) в Code Review – Mast