Это потому что вы синхронизируете только когда вы устанавливаете переменную names
, а не когда вы читаете ее. Таким образом, между чтением и записью может выполняться другой поток, и вы создадите два ArrayLists и заполните их данными, первый созданный будет иметь GC'ed.
Вам нужно поместить синхронизированный блок вокруг чтения и записи или добавить синхронизированный модификатор в метод.
public class Foo {
private ArrayList<String> names;
public void scan() {
synchronized (this)
if (names == null) {
this.names = new ArrayList<String>();
// fill the array with data
}
}
}
}