Обеспечивает ли 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

Не уверен, правильно ли моя логика синхронизирует выполнение или где я делаю неправильно. Любая помощь будет оценена по достоинству.

0 ответов

Другие вопросы по тегам