ConcurrentModificationException lors du cours de qualification de [Java Programmer, Silver SE 8](http://www.oracle.com/jp/education/certification/jse8-2489021-ja.html) mené dans le même effort. À propos des questions liées à
.java.util.ConcurrentModificationException
se produit lorsqu'une instance java.util.ArrayList non thread-safe
est modifiée à partir d'un autre thread, mais cela se produit également dans le traitement d'un seul thread. ..ConcurrentModificationException
qui se produit même dans un seul thread.DenaiConcurrentModificationException.java
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
for (String str : list) {
if ("C".equals(str)) {
list.remove(str);
} else {
System.out.println(str);
}
}
}
ConcurrentModificationException
sera levé.DeruConcurrentModificationException.java
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
list.add("E");
for (String str : list) {
if ("C".equals(str)) {
list.remove(str);
} else {
System.out.println(str);
}
}
}
Cette exception est levée lorsqu'une méthode qui détecte une modification parallèle dans un objet ne permet pas une telle modification.
Par exemple, il n'est généralement pas autorisé à un autre thread de modifier la collection pendant qu'un thread itère sur la collection.
Dans un tel environnement, les résultats du traitement itératif ne sont généralement pas garantis.
Quelques itérateurs(Iterator)Implémentation de(JREが提供するすべての一般的な目的のコレクションImplémentation deの、イテレータImplémentation deを含む)Est
Vous pouvez choisir de lever cette exception si ce comportement est détecté.
L'itérateur qui lève cette exception est appelé l'itérateur failfast.
Les itérateurs lancent des exceptions immédiatement et gracieusement pour éviter le risque de comportement imprévisible à des moments imprévisibles dans le futur.
Cette exception n'indique pas nécessairement que l'objet n'a pas été mis à jour en parallèle par un autre thread.
L'objet lève cette exception si un seul thread émet un ensemble de méthodes qui violent les conventions de l'objet.
Par exemple, si un thread modifie une collection directement lors de l'itération sur une collection avec un itérateur failfast.
L'itérateur lève cette exception.
ConcurrentModificationException
soit toujours lancée quand un thread modifie une collection directement en itérant avec *.java
/**
* An optimized version of AbstractList.Itr
*/
private class Itr implements Iterator<E> {}
Avec *, ConcurrentModificationException est levée s'il y a une différence entre expectedModCount et modCount à chaque fois que le curseur se déplace. Vous pouvez deviner le rôle de la propriété à partir du nom.
java
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
remove
incrémente modCount, ce qui provoque ConcurrentModificationException
.java
/*
* Private remove method that skips bounds checking and does not
* return the value removed.
*/
private void fastRemove(int index) {
modCount++;
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
}
System.arraycopy (elementData, index + 1, elementData, index, numMoved);
, vous pouvez voir que lorsque l'élément C est supprimé, l'élément suivant est déplacé vers le haut comme indiqué ci-dessous.
list.remove (" C ")
. Puisque 3 n'existe pas dans la première étape, le traitement se termine tel quel, le traitement se poursuit dans la deuxième étape, checkForComodification
est exécuté et une ConcurrentModificationException est lancée.Recommended Posts