2016-05-20 3 views
-1

Ich stieß vor kurzem auf einen Fehler bei der Ausführung meiner Runnable, die den Standort von Minenkarts aktualisiert. Main.UvehicleLocation2 ist ein HashMapjava.util.ConcurrentModificationException Fehler

[22:36:59] [Craft Scheduler Thread - 607/WARN]: Exception in thread "Craft Scheduler Thread - 607" 
[22:36:59] [Craft Scheduler Thread - 607/WARN]: org.apache.commons.lang.UnhandledException: Plugin CreativeControlByKubqoA v2.2.3 generated an exception while executing task 3019245 
at org.bukkit.craftbukkit.v1_9_R1.scheduler.CraftAsyncTask.run(CraftAsyncTask.java:56) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
at java.lang.Thread.run(Thread.java:745) 
Caused by: java.util.ConcurrentModificationException 
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1429) 
at java.util.HashMap$KeyIterator.next(HashMap.java:1453) 
at java.util.AbstractCollection.toArray(AbstractCollection.java:141) 
at java.util.ArrayList.<init>(ArrayList.java:177) 
at me.kubqoa.creativecontrol.tasks.VehiclesUpdateDB.run(VehiclesUpdateDB.java:19) 
at org.bukkit.craftbukkit.v1_9_R1.scheduler.CraftTask.run(CraftTask.java:71) 
at org.bukkit.craftbukkit.v1_9_R1.scheduler.CraftAsyncTask.run(CraftAsyncTask.java:53) 
... 3 more 

Dies ist der Code:

@Override 
public void run() { 
    List<Location> locations1 = new ArrayList<Location>(Main.UvehiclesLocation2.keySet()); 
    for (Location location : locations1) { 
     VehicleHelper.updateVehicle(location,Main.UvehiclesLocation2.get(location)); 
    } 
} 
+0

'Main.UvehiclesLocation2.keySet()' geändert wird, während Sie es in die neue Array-Liste kopiert werden. Sie benötigen exklusiven Zugriff auf diese Instanz, während Sie sie kopieren. (Oder verwenden Sie zum Beispiel eine 'ConcurrentHashMap'). –

+0

Wie ändern Sie den Typ von 'UvehiclesLocation2' von' HashMap' in 'ConcurrentHashMap'? –

+0

Ja. Wenn Sie es iterieren und gleichzeitig aktualisieren müssen, können Sie 'ConcurrentHashMap' verwenden. Insbesondere wird [iterating 'keySet()'] (https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentHashMap.html#keySet()) garantiert, kein '' zu werfen ConcurrentModificationException'. –

Antwort

0

Main.UvehiclesLocation2.keySet() geändert wird, während Sie es in das neue Array-Liste kopieren.

Sie benötigen entweder exklusiven Zugriff auf diese Instanz, während Sie sie kopieren (z. B. mit einem synchronized Block), oder Sie können stattdessen Main.UvehiclesLocation2 als ConcurrentHashMap ändern. From the Javadoc:

The view's iterator is a "weakly consistent" iterator that will never throw ConcurrentModificationException , and guarantees to traverse elements as they existed upon construction of the iterator, and may (but is not guaranteed to) reflect any modifications subsequent to construction.

+0

Ich habe den Typ in 'ConcurrentHashMap' geändert, aber jetzt, wenn ich versuche, auf die HashMap zuzugreifen, in einem anderen Teil des Codes mit' if (Main.UvehiclesLocation2.containsKey (location)) location = Main.UvehiclesLocation2.get (location); 'java.lang.NoSuchFieldError: UvehiclesLocation2' –

+0

Klingt so, als müssten Sie Ihren Code neu kompilieren. –

+0

Das funktioniert nicht, ich habe den gleichen Fehler gemacht. –