Обеспечивает ли compareAndSet AtomicLong безопасность потоков
Это продолжение моего предыдущего вопроса - Рефакторинг блоков синхронизации с сохранением порядка выполнения без изменений.
У меня есть синхронизированный блок в одной из функций, с которой я хочу избавиться, имея кое-что еще для уменьшения конкуренции и повышения производительности.
public CallCompletion startCall()
{
long currentTime;
Pending pending = null;
long lastStartTime = _lastStartTime.get();
currentTime = _clock.currentTimeMillis();
synchronized (_lock)
{
_lastStartTime = currentTime;
_tracker.getStatsWithCurrentTime(currentTime);
_sumOfOutstandingStartTimes += currentTime;
_callStartCountTotal++;
_tracker._callStartCount++;
if (_callStartsInLastSecondTracker != null) _callStartsInLastSecondTracker.addCall();
_concurrency++;
if (_concurrency > _tracker._concurrentMax) {
_tracker._concurrentMax = _concurrency;
}
pending = checkForPending();
}
if (pending != null)
{
pending.deliver();
}
return new CallCompletionImpl(currentTime);
}
Я пытаюсь заменить на AtomicLong для _lastStartTime
:
public CallCompletion startCall()
{
long currentTime;
Pending pending = null;
long lastStartTime = _lastStartTime.get();
currentTime = _clock.currentTimeMillis();
//synchronized (_lock)
//{
if (_lastStartTime.compareAndSet(lastStartTime, currentTime)) {
System.out.println("Inside atomic if -->" + Thread.currentThread().getName());
//_lastStartTime = currentTime;
_tracker.getStatsWithCurrentTime(currentTime);
_sumOfOutstandingStartTimes += currentTime;
_callStartCountTotal++;
_tracker._callStartCount++;
if (_callStartsInLastSecondTracker != null) _callStartsInLastSecondTracker.addCall();
_concurrency++;
if (_concurrency > _tracker._concurrentMax) {
_tracker._concurrentMax = _concurrency;
}
pending = checkForPending();
System.out.println("Leaving atomic if -->" + Thread.currentThread().getName());
}
// }
if (pending != null)
{
pending.deliver();
}
return new CallCompletionImpl(currentTime);
}
Однако, хотя большинство потоков входят и выходят из compareAndSet
блокировать последовательно, есть несколько потоков, в которых происходит сбой:
Inside atomic if -->pool-1-thread-3
Inside atomic if -->pool-1-thread-2
Leaving atomic if -->pool-1-thread-2
Leaving atomic if -->pool-1-thread-3
Не уверен, правильно ли моя логика синхронизирует выполнение или где я делаю неправильно. Любая помощь будет оценена по достоинству.