Я иногда использую переменную экземпляра volatile
в тех случаях, когда у меня есть два потока, считывающих / записывающих в него и не желающих накладные расходы (или потенциальный риск тупика) при снятии блокировки; например, поток таймера, периодически обновляющий int ID, который предоставляется как метод получения в некотором классе:
public class MyClass {
private volatile int id;
public MyClass() {
ScheduledExecutorService execService = Executors.newScheduledThreadPool(1);
execService.scheduleAtFixedRate(new Runnable() {
public void run() {
++id;
}
}, 0L, 30L, TimeUnit.SECONDS);
}
public int getId() {
return id;
}
}
Мой вопрос: учитывая, что JLS гарантирует только атомарное 32-битное чтение, есть ли смысл в когда-либо использовании volatile long? (т. е. 64-разрядная версия).
Предостережение : Пожалуйста, не отвечайте, сказав, что использование volatile
над synchronized
является случаем предварительной оптимизации; Я хорошо знаю, как / когда использовать synchronized
, но есть случаи, когда volatile
предпочтительнее. Например, при определении bean-компонента Spring для использования в однопоточном приложении я склоняюсь к предпочтению volatile
переменных экземпляра, поскольку нет гарантии, что контекст Spring инициализирует свойства каждого bean-компонента в основном потоке.