Hallo Coder,
Ich habe eine Exception gefunden! Yay! Das an sich ist ja nicht schwer.
Aber was genaus soll das sein?
Hier der Code der Klasse:
Ich habe nach einiger Recherche das Problem gelöst und wollte meine Lösung hier posten, damit niemand anderes noch an dieser Exception verzweifelt.
1. Wann tritt sie auf
Eine ConcurrentModificationException tritt auf, wenn von zwei verschiedenen Threads auf eine Liste zugegriffen wird, oder wenn während der Iteration (Durchgehen aller Objekte einer Liste), ein Objekt entfernt werden könnte.
2. Wie löst man es "richtig"
Falls es sich hierbei um einen Multi-Thread Umgebung handelt, könnt diese Klasse helfen:
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentMap.html
Bei einer Single-Thread Umgebung empfehlt sich eine Lösung mit lokaler Variable, die mit der "for"-Schleife Iteriert wird (oder mit Iteratoren, wie man das halt lieber macht):
Hier noch ein Link der von @manf gepostet wurde, bezüglich weiterer Möglichkeiten:
http://www.javacodegeeks.com/2011/05/avoid-concurrentmodificationexception.html
Ich hoffe ich konnte dem ein oder anderen helfen
MfG
_Baum_
Ich habe eine Exception gefunden! Yay! Das an sich ist ja nicht schwer.
Aber was genaus soll das sein?
Code:
[13:40:30 WARN]: [ScorpionPvP] Task #7 for ScorpionPvP v1.0 generated an exception
java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:819) ~[?:1.7.0_03]
at java.util.ArrayList$Itr.next(ArrayList.java:791) ~[?:1.7.0_03]
at pluesch.AntiLogout.TaktImpuls(AntiLogout.java:52) ~[?:?]
at pluesch.AntiLogout$1.run(AntiLogout.java:37) ~[?:?]
at org.bukkit.craftbukkit.v1_7_R2.scheduler.CraftTask.run(CraftTask.java:58) ~[spigot.jar:git-Spigot-1360]
at org.bukkit.craftbukkit.v1_7_R2.scheduler.CraftScheduler.mainThreadHeartbeat(CraftScheduler.java:345) [spigot.jar:git-Spigot-1360]
at net.minecraft.server.v1_7_R2.MinecraftServer.v(MinecraftServer.java:618) [spigot.jar:git-Spigot-1360]
at net.minecraft.server.v1_7_R2.DedicatedServer.v(DedicatedServer.java:273) [spigot.jar:git-Spigot-1360]
at net.minecraft.server.v1_7_R2.MinecraftServer.u(MinecraftServer.java:566) [spigot.jar:git-Spigot-1360]
at net.minecraft.server.v1_7_R2.MinecraftServer.run(MinecraftServer.java:472) [spigot.jar:git-Spigot-1360]
at net.minecraft.server.v1_7_R2.ThreadServerApplication.run(SourceFile:618) [spigot.jar:git-Spigot-1360]
Hier der Code der Klasse:
Code:
public class AntiLogout implements Listener{
private ArrayList<Player>spieler;
private ArrayList<Integer>timeout;
private MainFixes main;
private String prefix;
private Farben farben;
public AntiLogout(MainFixes m)
{
m.getServer().getScheduler().scheduleSyncRepeatingTask(m, new Runnable() {
public void run() {
TaktImpuls();
}
}, 60L, 20L);
spieler = new ArrayList<Player>();
timeout = new ArrayList<Integer>();
main=m;
prefix= main.getPrefix();
farben= main.getFarben();
}
protected void TaktImpuls()
{
if(!timeout.isEmpty())
{
for(Integer i:timeout)//Hier tritt die Excepion auf, da waehrend der Iteration evtl. Eintraege entfernt werden
{
int index=timeout.indexOf(i);
if(i<=0)
{
if(spieler.size()>index)
{
Player p=spieler.get(index);
removePvP(p);//Hier wird ein Eintrag entfernt
}
else
{
timeout.remove(i);
}
}
else
{
timeout.set(index, i-1);
}
}
}
}
public void addPvP(Player p)
{
if(spieler.contains(p))
{
int index= spieler.indexOf(p);
timeout.remove(index);
spieler.remove(index);
BarAPI.removeBar(p);
}
else
{
if(!p.getWorld().getName().equals("KitPvP"))
{
if(main.istHauptwelt(p.getWorld().getName()))
{
farben.rotFaerben(p);
p.sendMessage(prefix+"§cDu kannst den Spawn nicht mehr betreten!");
}
p.sendMessage(prefix+"§cFalls du ausloggst wirst du getötet!");
p.sendMessage(prefix+"§4*Du bist im PvP-Modus*");
}
}
spieler.add(p);
timeout.add(8);
if(p.getWorld().getName().equals("KitPvP"))
{
BarAPI.setMessage(p, "§4§l*PvP*", 8);
return;
}
BarAPI.setMessage(p, "§4§l*PvP*", 8);
}
public void removePvP(Player p)
{
if(spieler.contains(p))
{
int index= spieler.indexOf(p);
spieler.remove(index);
timeout.remove(index);//Entfernung eines Objekts
p.sendMessage(prefix+"§2*Du bist nicht mehr im PvP-Modus*");
BarAPI.removeBar(p);
farben.entfaerben(p);
}
}
//Events
@EventHandler
public void onPlayerLeave(PlayerQuitEvent e)
{
Player p=e.getPlayer();
if(spieler.contains(p))
{
if(main.check(p.getLocation()))
{
p.setHealth(0.0);
}
removePvP(p);
}
}
@SuppressWarnings("deprecation")
@EventHandler
public void PvPInteraktion(EntityDamageByEntityEvent e)
{
if(e.getEntity() instanceof Player)
{
Player angreifer;
Player opfer= (Player) e.getEntity();
Entity damager= e.getDamager();
if(damager instanceof Projectile)
{
damager=((Projectile) damager).getShooter();
}
if(damager instanceof Player)
{
angreifer = (Player) damager;
}
else
{
return;
}
if(angreifer.equals(opfer))
{
return;
}
if(main.istHauptwelt(opfer.getWorld().getName()))
{
if(main.check(angreifer.getLocation())&&main.check(opfer.getLocation())&&!main.hatSchutz(opfer)&&!main.hatSchutz(angreifer))
{
addPvP(angreifer);
addPvP(opfer);
}
}
else
{
if(main.check(angreifer.getLocation())&&main.check(opfer.getLocation()))
{
addPvP(angreifer);
addPvP(opfer);
}
}
}
}
@EventHandler
public void onDeath(PlayerDeathEvent e)
{
Player p= e.getEntity();
if(spieler.contains(p))
{
this.removePvP(p);
}
}
}
//Wenn ihr Teile oder den ganzen Code haben wollt: bedient euch ;)
Ich habe nach einiger Recherche das Problem gelöst und wollte meine Lösung hier posten, damit niemand anderes noch an dieser Exception verzweifelt.
1. Wann tritt sie auf
Eine ConcurrentModificationException tritt auf, wenn von zwei verschiedenen Threads auf eine Liste zugegriffen wird, oder wenn während der Iteration (Durchgehen aller Objekte einer Liste), ein Objekt entfernt werden könnte.
2. Wie löst man es "richtig"
Falls es sich hierbei um einen Multi-Thread Umgebung handelt, könnt diese Klasse helfen:
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentMap.html
Bei einer Single-Thread Umgebung empfehlt sich eine Lösung mit lokaler Variable, die mit der "for"-Schleife Iteriert wird (oder mit Iteratoren, wie man das halt lieber macht):
Code:
for(Integer i : new ArrayList<Integer>(timeout))//by MiCrJonas1997
Hier noch ein Link der von @manf gepostet wurde, bezüglich weiterer Möglichkeiten:
http://www.javacodegeeks.com/2011/05/avoid-concurrentmodificationexception.html
Ich hoffe ich konnte dem ein oder anderen helfen
MfG
_Baum_
Zuletzt bearbeitet: