【问题标题】:Java Events - java.util.ConcurrentModificationExceptionJava 事件 - java.util.ConcurrentModificationException
【发布时间】:2013-08-28 03:30:21
【问题描述】:

是的,我确定这个问题存在,但我已经尝试了答案,我想我需要一个自定义答案..

无论如何,正如标题所示,我得到了一个 java.util.ConcurrentModificationException

所有这些都在它自己的线程中调用。

我如何举办活动:

private void setUpMainGameTimer() {
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                try{
                    TickEvent.call();
                } catch (Exception e){
                    e.printStackTrace();
                }
            }
        }, 0, gameSpeed);
    }

我的堆栈跟踪。

java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
    at java.util.ArrayList$Itr.next(Unknown Source)
    at net.njar.rpg.Event.EventCaller.call(EventCaller.java:15)
    at net.njar.rpg.Event.TickEvent.call(TickEvent.java:10)
    at net.njay.rpg.Main.Main$1.run(Main.java:213)
    at java.util.TimerThread.mainLoop(Unknown Source)
    at java.util.TimerThread.run(Unknown Source)

这是我的 EventCaller 类。

public class EventCaller<Type extends Event> {

    @SuppressWarnings("unchecked")
    public void call(ArrayList<Listener> listeners, Event e){
        //Iterate through all of the listeners
        for (Listener h : listeners){

            //Iterate through each method
            for (Method m : h.getClass().getMethods()){
                //check if @EventHandler is present
                if (m.isAnnotationPresent(EventHandler.class)){
                    //get params
                    for (Class<?> param : m.getParameterTypes()){
                        //check if parameter is the same type as the passed event
                        if (param.equals(e.getClass())) {
                            try {
                                m.invoke(h, (Type) e);
                            } catch(Exception e1){
                                e1.printStackTrace();
                            }
                        }

                    }
                }
            }
        }
    }
}

以及tick事件:

public class TickEvent extends Event{
    private static long id = 0;

    public static void call(){
        id++;
        TickEvent e = new TickEvent();
        EventCaller<TickEvent> caller = new EventCaller<TickEvent>();
        caller.call(Event.getListeners(), e);
    }

     public long getTickID(){
         return TickEvent.id;
     }

     public static long getcurrentTickID(){
         return id;
     }
}

事件类:

public class Event {

    private static ArrayList<Listener> listeners = new ArrayList<Listener>();

    public static void addListener(Listener listener){
        listeners.add(listener);
    }

    public synchronized static ArrayList<Listener> getListeners(){
        return Event.listeners;
    }

}

请告诉我您还需要什么。

【问题讨论】:

标签: java java.util.concurrent


【解决方案1】:

EventCaller 类中检查您的public void call(ArrayList&lt;Listener&gt; listeners, Event e) 方法。

在for循环内

for (Listener h : listeners){...}

h 在迭代完成之前得到修饰符。具体检查 m.invoke(h, (Type) e); 调用的作用。它不应该修改 h。

【讨论】:

    【解决方案2】:

    答案 1:可以使用 list.toArray() 将列表转换为数组并在数组上进行迭代。这种方法不 如果列表很大,建议使用。

    答案 2:通过将代码包装在同步块中,可以在迭代时锁定整个列表。如果应用程序高度并发,这种方法会对应用程序的可扩展性产生不利影响。

    答案 3:JDK 1.5 为您提供了 ConcurrentHashMap 和 CopyOnWriteArrayList 类,它们提供了更好的可伸缩性,并且 ConcurrentHashMap.iterator() 返回的迭代器在保持线程安全的同时不会抛出 ConcurrentModificationException。

    答案 4:通过迭代器“it”删除当前对象,该迭代器“it”引用了基础集合“myStr”。 Iterator 对象为此提供了 it.remove() 方法。

      public class EventCaller<Type extends Event> {
    
         @SuppressWarnings("unchecked")
         public void call(ArrayList<Listener> listeners, Event e){
    
             //Iterate through all of the listeners
             for(Iterator<Listener> iter = listeners.iterator(); iter.hasNext(); ) {
                 Listener h = iter.next();
    
             }
         }
      }
    

    }

    【讨论】:

      猜你喜欢
      • 2012-01-23
      • 1970-01-01
      • 1970-01-01
      • 2014-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-28
      相关资源
      最近更新 更多