Если переменная экземпляра не является неизменной, то состояние этой переменной все еще можно изменить, даже если она является конечной. Взять, к примеру:
private final List<Foo> foos = new ArrayList<Foo>();
public void addFoo(Foo newFoo){
foos.add(newFoo);
}
public Foo popFoo(){
return foos.remove(0);
}
В этой ситуации, даже если foos
является окончательным, поток B может добавить Foo
, пока поток A пытается удалить элемент, что приводит к потенциально значимому состоянию.
Учебное пособие по синхронизированным методам, упомянутое в других примерах, является правильным, так как чтение конечная переменная не нуждается в синхронизации. Однако, если переменная является изменяемой (как List<T>
), то запись в эту переменную должна быть синхронизирована, чтобы гарантировать отношение «происходит до». Однако если переменная является неизменной, то, конечно, запись в эту переменную в любом случае запрещена, поэтому синхронизировать не нужно.