9 Replies Latest reply: Apr 24, 2008 2:46 PM by 807591 RSS

    ConcurrentModificationException BAD STACKTRACE

    807591
      I have problem in code but the stacktrace is not very helpful so I post here
               public boolean triggerEntity(final QuestTrigger trigger, final Entity entity)
               {
                    //HashMap<String, Quest> clone = (HashMap<String, Quest>)quests.clone();
                    boolean handled = false;
               
                    try
                    {
                         synchronized(this)
                         {
                              HashMap<String, Quest> clone = (HashMap<String, Quest>)quests.clone();
                              Iterator questIterator = clone.values().iterator();
                          while(questIterator.hasNext())
                              //for(final Quest quest : quests.values())//clone.values())
                              {
                                   Quest quest = (Quest)questIterator.next();
                                   if(entity instanceof Npc)
                                        if(!quest.npcAssociated(((Npc)entity).getID()))
                                             continue;
                                        
                                   if(entity instanceof InvItem)
                                        if(!quest.itemAssociated(((InvItem)entity).getID()))
                                             continue;
                                             
                                   if(entity instanceof GameObject)
                                        if(!quest.objectAssociated(((GameObject)entity).getID()))
                                             continue;
                                             
                                   final Quest finalquest = quest;
                                   new Thread(new Runnable()
                                   {
                                        public void run()
                                        {
                                             finalquest.triggerEntity(trigger, entity);
                                        }
                                   }).start();
                              
                                   handled = true;
                              }
                         }
                    } catch(Exception e)
                    {
                         e.printStackTrace();
                    }
               
                    return handled;
           }
      nice error stace trace can't even understand what it is about its not even close to anything related regarding class files note I did some changes to the statement but this exception keeps happening yup if I can't know whats wrong with my coding how am I expected to fix it?


      [java] Exception in thread "Thread-2" java.util.ConcurrentModificationExcep
      tion
      [java] at java.util.AbstractList$Itr.checkForComodification(AbstractLis
      t.java:372)
      [java] at java.util.AbstractList$Itr.next(AbstractList.java:343)
        • 1. Re: ConcurrentModificationException BAD STACKTRACE
          807591
          isyour method (triggerEntity) really supposed to be recursive?
          • 2. Re: ConcurrentModificationException BAD STACKTRACE
            791266
            That's not the full stacktrace?

            Looks like you modifying the map while you are iterating over it.

            Kaj
            • 3. Re: ConcurrentModificationException BAD STACKTRACE
              807591
              [java] Exception in thread "Thread-2" java.util.ConcurrentModificationExcep
              tion
              Sun doc says:
              it is not generally permssible for one thread to modify a Collection while another thread is iterating over it. In general, the results of the iteration are undefined under these circumstances.
              Better check the flow of threads. Since you have used the keyword "synchronized" there is a possibility for what the Sun doc says.
              • 4. Re: ConcurrentModificationException BAD STACKTRACE
                791266
                Better check the flow of threads. Since you have used the keyword "synchronized" there is a possibility for what the Sun doc says.
                You can get that exception with only one thread as well.
                • 5. Re: ConcurrentModificationException BAD STACKTRACE
                  807591
                  kajbj wrote:
                  Better check the flow of threads. Since you have used the keyword "synchronized" there is a possibility for what the Sun doc says.
                  You can get that exception with only one thread as well.
                  Yes you are correct...also
                  Sun doc says:
                  Note that this exception does not always indicate that an object has been concurrently modified by a different thread. If a single thread issues a sequence of method invocations that violates the contract of an object, the object may throw this exception.
                  I dont think so we need the keyword "synchronized" if the application using single thread. Hence i refered for multiple threads.
                  • 6. Re: ConcurrentModificationException BAD STACKTRACE
                    807591
                    it looks recursive but its not Quest class has a
                                     
                    
                    public abstract void triggerEntity(QuestTrigger type, Entity entity);
                    then every quest I make like
                    public class NoobQuest extends Quest
                    has
                         public void triggerEntity(QuestTrigger trigger, Entity entity)
                         {
                              if(entity instanceof Npc) // This entity is an NPC.
                              {
                              BLAH BLAH
                              }
                         }
                    and YES thats the complete STACKTRACE.


                    Also inside the triggerEntity lets say inside the NoobQuest I do modify a variable thats saved in the Quest class it self could that be it? and how do I stop it honestly? can someone post a example code to stop it

                    Edited by: MrConcurrent on Apr 24, 2008 12:45 PM
                    • 7. Re: ConcurrentModificationException BAD STACKTRACE
                      807591
                      kajbj wrote:
                      You can get that exception with only one thread as well.
                      As I discovered yesterday, while messing around with a card game. My game loop iterated over the collection of all players currently in the game to give them a turn. If they ran out of cards during the turn, they needed to be removed from the game. But as I was iterating over the list, it wouldn't let me remove them...not always, but occasionally. I was baffled by it's inconsistency.
                      • 8. Re: ConcurrentModificationException BAD STACKTRACE
                        807591
                        im still how u say baffled because I see no way to fix this? im guessing add a arraylist to store the quests that are associated with that loop in another array? then loop em again to start threads? or what?
                        • 9. Re: ConcurrentModificationException BAD STACKTRACE
                          807591
                          and YES thats the complete STACKTRACE.
                          No, it isn't. If it were the complete stack trace, and if it was in any way caused by your code, then one of your classes would appear somewhere in the trace. Perhaps you're not seeing the entire trace for some reason. You should figure out that reason.

                          I'm not convinced that the piece of stack trace you show is in any way related to the code you posted. It indicates a concurrent modification of an AbstractList, yet your iterator is on the values of a HashMap. Perhaps the HashMap implementation is returning its values in some sort of AbstractList implementation, but it's unlikely.

                          If the exception is somehow related to the code you posted, then the clone() call might not be making a sufficiently deep clone of the original map. You're probably better off calling toArray(), and iterating over that array.

                          And then there's the new thread ... does your code really need to be multi-threaded? If yes, then use a thread pool, don't just spin up threads every time you think you need one. Spinning up new threads from deep within your code is a recipe for disaster -- at least until you run out of available threads or memory for thread stacks.