ConcurrentModificationException выбрасывается, потому что вы перебираете список, в то время как некоторые потоки добавляют элемент в список.
Вы используете Collections.synchronizedList , где add иметоды удаления синхронизируются с помощью блокировки списка.Чтобы запретить другим добавлять что-либо в список во время итерации списка с помощью итератора, необходимо заблокировать этот список следующим образом.
synchronized(list){
Iterator i = list.iterator();
while (i.hasNext()){
//do something
}
}
Вы не делаете этого, вы синхронизируете getNext метод, но не с блокировкой списка, и вы синхронизируете только при вызове метода next () , которого недостаточно.
public synchronized T getNext() {
return this.elements.next();;
}
Если вы хотите использовать свой шаблонвам нужно создать копию списка в вашем RoundRobinIterable
import java.util.Iterator;
import java.util.List;
import com.google.common.collect.Iterables;
public class RoundRobinIterable<T> {
private final Iterator<T> elements;
public RoundRobinIterable(final List<T> elements) {
List<T> copyOfElements = new ArrayList<>(elements);
this.elements = Iterables.cycle(copyOfElements).iterator();
}
public synchronized T getNext() {
return this.elements.next();;
}
}
Теперь никто не может добавить элемент в скопированный список во время итерации списка, но вы не получите элементы, добавленные вОригинальный список после того, как вы создали RoundRobinIterable.Если вы хотите получить элементы, которые добавляются позже, то лучше использовать что-то еще, чем List.Например, ConcurrentLinkedQueue.