фон
Я хотел бы понять, почему фрагмент кода делает не бросить NullPointerException.Почему этот код не выдает исключение NullPointerException?
Исходный код
Рассмотрим следующий код:
public class Agent {
public List files = new ArrayList();
public void deliver() {
if(files != null && files.iterator().hasNext()) {
File file = (File)files.iterator().next();
}
files = new ArrayList();
}
}
Метод deliver
вызывается несколько раз, в то время как следующий код запускается в отдельном потоке:
public void run() {
agent.files = null;
}
Существует только одиночный agent
экземпляр.
Проблема
NullPointerException никогда не выброшен.
Однако, когда deliver
метод паузы, даже на 0 миллисекунд, NullPointerException отбрасывается, как и ожидалось:
public void deliver() {
if(files != null) {
Thread.currentThread().sleep(0);
if(files.iterator().hasNext()) {
File file = (File)files.iterator().next();
}
}
files = new ArrayList();
}
Мое понимание было то, что есть, в теории, состояние гонки между проверкой для files == null
и вызова files.iterator().hasNext()
. На практике я не могу вызвать состояние гонки без введения паузы (т. Е. Разделения нулевой проверки из последующего вызова метода).
Вопрос
Почему первый deliver
метод не сгенерирует исключение, когда проверка нулевой и использование объединены в одном заявлении?
Можете ли вы опубликовать выходные данные 'javap', где соответствующие области состояния гонки? – hexafraction
Что происходит, когда вы делаете 'файлы' 'volatile'? – OldCurmudgeon