java.util.AbstractList$Itr.checkForComodification Triple Events

Ich einen server laufen lassen, und es hat einen event-handler, mit einem timing-system
Bei mir laufen 3 von Ihnen in einer Reihe, es gibt diese Ausnahme

Exception in thread "Thread-8" java.util.ConcurrentModificationException
        at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
        at java.util.AbstractList$Itr.next(AbstractList.java:343)
        at EventManager.run(EventManager.java:77)
        at java.lang.Thread.run(Thread.java:662)

hier ist die Methode, dass die Frage kommt:

EventManager.getSingleton().addEvent( new Event() { 
                public void execute(EventContainer c) {
                    p.createProjectile(p.absY, p.absX, offsetY, offsetX, 1166, 43, 31, 70, p2.playerId);
                    c.stop(); //stops the event from running
                }
            }, 950); //in ms (1 second = 1000 ms)
EventManager.getSingleton().addEvent( new Event() { 
                public void execute(EventContainer c) {
                    p2.applyDAMAGE(misc.random(25));
                    c.stop(); //stops the event from running
                }
            }, 1300); //in ms (1 second = 1000 ms)
            p.secondsTillNextDfsSpecial = 120;
EventManager.getSingleton().addEvent( new Event() { 
                public void execute(EventContainer c) {
                    p.secondsTillNextDfsSpecial--;
                    if (p.secondsTillNextDfsSpecial == 0) {
                        p.canPerformDfsSpecial = true;
                        c.stop(); //stops the event from running
                    }
                }
            }, 1000); //in ms (1 second = 1000 ms)

import java.util.ArrayList;
import java.util.List;

/**
 * Manages events which will be run in the future.
 * Has its own thread since some events may need to be ran faster than the cycle time
 * in the main thread.
 * 
 * @author Graham
 *
 */
public class EventManager implements Runnable {


/**
 * A reference to the singleton;
 */
private static EventManager singleton = null;

/**
 * A list of events that are being executed.
 */
private List<EventContainer> events;

/**
 * Initialise the event manager.
 */
private EventManager() {
    events = new ArrayList<EventContainer>();
}

/**
 * The event manager thread. So we can interrupt it and end it nicely on shutdown.
 */
private Thread thread;

/**
 * Gets the event manager singleton. If there is no singleton, the singleton is created.
 * @return The event manager singleton.
 */
public static EventManager getSingleton() {
    if(singleton == null) {
        singleton = new EventManager();
        singleton.thread = new Thread(singleton);
        singleton.thread.start();
    }
    return singleton;
}

/**
 * Initialises the event manager (if it needs to be).
 */
public static void initialise() {
    getSingleton();
}

/**
 * The waitFor variable is multiplied by this before the call to wait() is made.
 * We do this because other events may be executed after waitFor is set (and take time).
 * We may need to modify this depending on event count? Some proper tests need to be done.
 */
private static final double WAIT_FOR_FACTOR = 0.5;

@Override
/**
 * Processes events. Works kinda like newer versions of cron.
 */
public synchronized void run() {
    long waitFor = -1;
    List<EventContainer> remove = new ArrayList<EventContainer>();

    while(true) {

        //reset wait time
        waitFor = -1;

        //process all events
        for(EventContainer container : events) {
            if(container.isRunning()) {
                if((System.currentTimeMillis() - container.getLastRun()) >= container.getTick()) {
                    container.execute();
                }
                if(container.getTick() < waitFor || waitFor == -1) {
                    waitFor = container.getTick();
                }
            } else {
                //add to remove list
                remove.add(container);
            }
        }

        //remove events that have completed
        for(EventContainer container : remove) {
            events.remove(container);
        }
        remove.clear();

        //no events running
        try {
            if(waitFor == -1) {
                wait(); //wait with no timeout
            } else {
                //an event is running, wait for that time or until a new event is added
                int decimalWaitFor = (int)(Math.ceil(waitFor*WAIT_FOR_FACTOR));
                wait(decimalWaitFor);
            }
        } catch(InterruptedException e) {
            break; //stop running
        }
    }
}

/**
 * Adds an event.
 * @param event The event to add.
 * @param tick The tick time.
 */
public synchronized void addEvent(Event event, int tick) {
    events.add(new EventContainer(event,tick));
    notify();
}

/**
 * Shuts the event manager down.
 */
public void shutdown() {
    this.thread.interrupt();
}

}</code></pre>
  • Poste bitte den code für EventManager. Auch, es wäre schön, wenn Sie reduzieren den code, dass ist irrelevant für das problem. Sie haben nur ein thread in deine app? Ist das eine Swing-Anwendung?
  • Im Grunde sind Sie machen änderungen an einer Sammlung während der Iteration über es, aber das passiert in EventManager code.
  • Zeile 77 mit Bezug auf eine Erhebung. Und, vermutlich, dass Sie nicht mit einem synchronisierten Sammlung. Das beheben.
  • Hinzugefügt wurde die Klasse eventmanager, lassen Sie mich wissen, ob weitere Hilfsmittel notwendig sind.
InformationsquelleAutor Travis | 2011-04-02
Schreibe einen Kommentar