Iterador à prova de falhas vs Iterador à prova de falhas
1. Introdução
Neste artigo, vamos apresentar o conceito de Fail-Fast e Fail-SafeIterators.
Os sistemas Fail-Fast abortam a operação o mais rápido possível, expondo as falhas imediatamente e parando toda a operação.
Considerando que,Fail-Safe systems don’t abort an operation in the case of a failure. Such systems try to avoid raising failures as much as possible.
2. Fail-FastIterators
Os iteradores fail-fast em Java não funcionam quando a coleção subjacente é modificada.
Collections mantém um contador interno chamadomodCount. Cada vez que um item é adicionado ou removido deCollection, este contador é incrementado.
Ao iterar, em cada chamada denext(), o valor atual demodCount é comparado com o valor inicial. Se houver uma incompatibilidade, ele lançaConcurrentModificationException que aborta toda a operação.
Iteradores padrão paraCollections dejava.util package, comoArrayList,HashMap, etc. são Fail-Fast.
ArrayList numbers = // ...
Iterator iterator = numbers.iterator();
while (iterator.hasNext()) {
Integer number = iterator.next();
numbers.add(50);
}
No trecho de código acima, oConcurrentModificationException é lançado no início de um próximo ciclo de iteração após a modificação ter sido realizada.
Não é garantido que o comportamento Fail-Fast aconteça em todos os cenários, pois é impossível prever o comportamento em caso de modificações simultâneas. These iterators throw ConcurrentModificationException on a best effort basis.
Se durante a iteração emCollection,an item is removed using Iterator‘s remove() method, that’s entirely safe and doesn’t throw an exception.
No entanto, se o métodoCollection’sremove() for usado para remover um elemento, ele lançará uma exceção:
ArrayList numbers = // ...
Iterator iterator = numbers.iterator();
while (iterator.hasNext()) {
if (iterator.next() == 30) {
iterator.remove(); // ok!
}
}
iterator = numbers.iterator();
while (iterator.hasNext()) {
if (iterator.next() == 40) {
numbers.remove(2); // exception
}
}
3. Iteradores à prova de falhas
Os iteradores à prova de falhas favorecem a falta de falhas em detrimento da inconveniência do tratamento de exceções.
Esses iteradores criam um clone doCollectione real e iteram sobre ele. Se ocorrer alguma modificação após a criação do iterador, a cópia ainda permanecerá intocada. Portanto, essesIterators continuam em loop sobreCollection, mesmo que seja modificado.
No entanto, é importante lembrar que não existe um iterador verdadeiramente à prova de falhas. O termo correto é Fracamente Consistente.
Isso significa,if aCollection is modified while being iterated over, what the Iterator sees is weakly guaranteed. Esse comportamento pode ser diferente paraCollections diferentes e está documentado nos Javadocs de cada um dessesCollection.
Porém, o Fail-SafeIterators tem algumas desvantagens. Uma desvantagem é que oIterator isn’t guaranteed to return updated data from the Collection, pois está trabalhando no clone em vez doCollection real.
Outra desvantagem é o overhead de se criar uma cópia doCollection, tanto em relação ao tempo quanto à memória.
Iterators emCollections do pacotejava.util.concurrent, comoConcurrentHashMap,CopyOnWriteArrayList, etc. são à prova de falhas por natureza.
ConcurrentHashMap map = new ConcurrentHashMap<>();
map.put("First", 10);
map.put("Second", 20);
map.put("Third", 30);
map.put("Fourth", 40);
Iterator iterator = map.keySet().iterator();
while (iterator.hasNext()) {
String key = iterator.next();
map.put("Fifth", 50);
}
No snippet de código acima, estamos usando Fail-SafeIterator. Portanto, mesmo que um novo elemento seja adicionado aCollection durante a iteração, ele não lança uma exceção.
O iterador padrão_ for the _ConcurrentHashMap é fracamente consistente. Isso significa que esteIterator pode tolerar modificações simultâneas, percorre os elementos como eles existiam quandoIterator foi construído e pode (mas não é garantido que) reflita modificações emCollection após a construção de oIterator.
Portanto, no trecho de código acima, a iteração é repetida cinco vezes, o que significait does detect the newly added element to the Collection.
4. Conclusão
Neste tutorial, vimos o que significa Fail-Safe e Fail-FastIterators e como eles são implementados em Java.
O código completo apresentado neste artigo está disponívelover on GitHub.