De ConcurrentModificationException treedt op wanneer wordt geprobeerd een object gelijktijdig te wijzigen terwijl dit niet is toegestaan. Deze uitzondering komt meestal voor als men met werkt Java Collection-klassen .
Bijvoorbeeld - Het is niet toegestaan dat een thread een verzameling wijzigt terwijl een andere thread eroverheen loopt. Dit komt omdat het resultaat van de iteratie daarmee ongedefinieerd wordt. Sommige implementaties van de Iterator-klasse genereren deze uitzondering, inclusief alle algemene implementaties van Iterator die door de JRE worden geleverd. Iterators die dit doen worden genoemd faal-snel omdat ze snel een uitzondering maken zodra ze een dergelijke situatie tegenkomen, in plaats van op enig moment in de toekomst met onbepaald gedrag van de collectie te maken te krijgen.
baudrate in Arduino
Opmerking:Het is niet verplicht dat deze uitzondering alleen wordt gegenereerd wanneer een andere thread een Collection-object probeert te wijzigen. Het kan ook gebeuren als een enkele thread een aantal methoden heeft aangeroepen die proberen het contract van het object te schenden. Dit kan gebeuren wanneer een thread het Collection-object probeert te wijzigen terwijl dit door sommigen wordt herhaaldfail-fast iterator, zal de iterator de uitzondering genereren.
Voorbeeld
import java.awt.List; import java.util.*; public class Concurrentmodificationexception { public static void main(String[] args) { ArrayList list = new ArrayList(); list.add(1); list.add(2); list.add(3); list.add(4); list.add(5); Iterator it = list.iterator(); while (it.hasNext()) { Integer value = it.next(); System.out.println('List Value:' + value); if (value.equals(3)) list.remove(value); } } }
Uitgang:
Dit bericht zegt dat de uitzondering wordt gegenereerd wanneer de volgende methode wordt aangeroepen, terwijl de iterator de lijst itereert en we er tegelijkertijd wijzigingen in aanbrengen. Maar als we wijzigingen aanbrengen in de hashmap, zoals hieronder aangegeven, zal er geen uitzondering optreden, omdat de grootte van de hashmap niet verandert.
quicksort-algoritme
Bijvoorbeeld-
import java.awt.List; import java.util.*; public class concurrentmodificationexception { public static void main(String[] args) { HashMap map = new HashMap(); map.put(1, 1); map.put(2, 2); map.put(3,3); Iterator it = map.keySet().iterator(); while(it.hasNext()) { Integer key = it.next(); System.out.println('Map Value:' + map.get(key)); if (key.equals(2)) { map.put(1, 4); } } } }
Uitgang:
Map Value:1 Map Value:2 Map Value:3
Dit voorbeeld werkt prima, want terwijl de iterator over de kaart itereert, verandert de grootte van de kaart niet. Alleen de kaart wordt bijgewerkt in de als verklaring .
Constructeurs van ConcurrentModificationException
Er zijn 4 soorten constructors van ConcurrentModificationException -
bellen sorteren in algoritme
- openbare ConcurrentModificationException() -
Hierdoor wordt een ConcurrentModificationException zonder parameters gemaakt. - public ConcurrentModificationException(String-bericht)
Hierdoor wordt een ConcurrentModificationException gemaakt met een gedetailleerd bericht waarin de uitzondering wordt gespecificeerd. - public ConcurrentModificationException (werpbare oorzaak)
Hierdoor wordt een ConcurrentModificationException gemaakt met een oorzaak en een bericht dat is (cause==null?null:cause.toString()). De oorzaak wordt later opgehaald door Throwable.getCause(). - public ConcurrentModificationException(String-bericht, Gooibare oorzaak)
Hierdoor wordt een ConcurrentModificationException gemaakt met een gedetailleerd bericht en een oorzaak. (oorzaak==null?null:oorzaak.toString()). Het bericht wordt later opgehaald door Throwable.getMessage() en de oorzaak wordt later opgehaald door Throwable.getCause().
Hoe kan ik ConcurrentModificationException vermijden in een omgeving met meerdere threads?
Om de ConcurrentModificationException in een omgeving met meerdere threads te vermijden, kunnen we de volgende manieren volgen:
- In plaats van de collectieklasse te herhalen, kunnen we de array herhalen. Op deze manier kunnen we heel goed werken met kleine lijsten, maar dit zal de prestaties verminderen als de array-grootte erg groot is.
- Een andere manier is om de lijst te vergrendelen door deze in het gesynchroniseerde blok te plaatsen. Dit is geen effectieve aanpak, omdat hierdoor het enige doel van het gebruik van multi-threading wordt opgegeven.
- JDK 1.5 of hoger biedt de klassen ConcurrentHashMap en CopyOnWriteArrayList. Deze klassen helpen ons bij het vermijden van gelijktijdige wijzigingsuitzonderingen.
Hoe ConcurrentModificationException vermijden in een single-threaded omgeving?
Door de functie remove() van iterator te gebruiken, kunt u een object verwijderen uit een onderliggend verzamelobject.