Как вы, вероятно, видели, снимок сделан в этом методе
public boolean addIfAbsent(E e) {
Object[] snapshot = getArray();
return indexOf(e, snapshot, 0, snapshot.length) >= 0 ? false :
addIfAbsent(e, snapshot);
}
, который в конце вызывает метод, который вы задали в своем вопросе.
Итак, если есть манипуляции с массив между полученным снимком и блокировкой, блокируемой текущим потоком, они должны обрабатываться правильно.
Существуют различные способы, как такая манипуляция может происходить между этими двумя моментами времени, например, поток, который вызывает addIfAbsent
метод прерывается планировщиком.
Другая, не столь маловероятная ситуация, если список часто записывается, будет состоять в том, что блокировка фактически блокируется другим потоком, когда текущий поток пытается заблокировать его, поэтому должен ждать, пока другой поток завершит свою работу (которая могла бы добавить элемент в список) и разблокировал блокировку, прежде чем он сможет заблокировать саму блокировку.