Синхронизировать метод ScheduledFuture.cancel()

Приведенный ниже код вырезан из книги "Программирование параллелизма на JVM: освоение синхронизации, STM и актеры"

Я не понимаю, почему автор синхронизирует метод stopEnergySource, который просто отменяет задачу ScheduledFuture, которая представлена ​​переменной replenishTask? Нет других методов, которые используют эту переменную. Желательно ли практиковать синхронизацию вызовов Future.cancel или это просто необходимо для ScheduledFuture?

public class EnergySource {
  //...
  private static final ScheduledExecutorService replenishTimer =
    Executors.newScheduledThreadPool(10);
  private ScheduledFuture<?> replenishTask;

  private EnergySource() {}

  private void init() {   
    replenishTask = replenishTimer.scheduleAtFixedRate(new Runnable() {
      public void run() { replenish(); }
    }, 0, 1, TimeUnit.SECONDS);
  }

  public static EnergySource create() {
    final EnergySource energySource = new EnergySource();
    energySource.init();
    return energySource;
  }

  public long getUnitsAvailable() { 
    //...
  }

  public long getUsageCount() { 
    //...
  }

  public boolean useEnergy(final long units) {
    //...
  }

  public synchronized void stopEnergySource() { // what for **synchronized** is?
    replenishTask.cancel(false); 
  }

  private void replenish() { 
    //...
  }
} 

1 ответ

Нет других методов, которые используют эту переменную. Желательно ли практиковать синхронизацию вызовов Future.cancel или это просто необходимо для ScheduledFuture?

Я считаю, что автор кода пытается создать барьеры памяти в случае, если другой поток пытается вызвать stopEnergySource() это начало работу в первую очередь.

Однако, если это было так, то init() метод также должен быть synchronized потому что они не делают безопасную публикацию replenishTask поле. Это поле не final и компилятор может иметь create(...) вернуться, но продолжить строительство и инициализацию EnergySource возразить позже.

Если бы несколько потоков создавали и останавливали эти объекты, вы могли бы легко получить NPE в stopEnergySource(...)даже с synchronized Ключевое слово на нем.

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