Spawning and completion of a person in a sim game (in Java)

I am developing a simulator based on a 2D mesh. Progress is good. Understood code very well over the last few days, and I had some problems today.

I build two rooms, set the position of the door and create a person. A person has 2 types of rooms that they must visit in order to recover (this is a remake of the Theme Hospital). I press the Caviar button, the face moves along the grid from the screen, and then, when the caviar is finished, they get their first way to the first room, then the second, and then back to the end point of the appearance.

When I say the appearance point, I mean the point from the screen / grid, when I say the end point of the appearance, I mean the point where the person, when the spawning cycle is finished, and they are completely on the screen / grid.

Now the problem arises, what to do with the "man" (which is an independent object), ends? Should I just set the boolean so that they cease to be "active", but the data on them remains? I was not sure, so I tried to simply remove them from the ArrayList objects of the people in which they were contained.

I did this by assigning a numerical value to each person at creation, which was the same as their new position in ArrayList, and then when they were deleted using that number. I know that flooring itself, but now I'm testing only one person. If anyone can help me with this, fantastic! But I suppose this is more of a question.

When a person needs to be deleted, they are there, and I check the size of the arraylist, and then I get the following error ... "Exception in thread" AWT-EventQueue-0 "java.util.ConcurrentModificationException"

I did some research, and I understand that this is due to the synchronization of objects in different threads, but I'm not sure that I have more than one thread. I have one timer, and I don't think ArrayList people are available elsewhere.

Any thoughts? Ideas? Suggestions? Comments on this?

Thanks in advance!

(I will post the video soon and update this question with a link to it)

+4
source share
3 answers

As a rule, I give each person or entity or whatever the Boolean field called isMarkedForDeletion. Then, during the main loop, they are either informed of update (), or if they are marked for deletion, their index will be added to the deletion list . After you fill out the deletion list, you can iterate over the deletion list and remove these objects from the main list. Alternatively, you can simply iterate back and pull from the tail of the list.

This may or may not explain your ConcurrentModificationException - I have never received them when working with ArrayList before. However, I got them from LinkedList, and that was for the very reason that you described and had nothing to do with streams. The actual reason was the use of the Iterator. The following will throw a ConcurrentModificationException:

for (Iterator i = list.iterator(); i.hasNext();) { Person o = i.next(); o.update(); if (list.isMarkedForDeletion()) { list.remove(o); } } 

This will not throw an exception:

 ArrayList deletedObjects = new ArrayList(); for (Iterator i = list.iterator(); i.hasNext();) { Person o = i.next(); o.update(); if (list.isMarkedForDeletion()) { deletedObjects.add(o); } } for (int i = 0; i < deletedObjects.size(); i++) { list.remove(deletedObjects.get(i)); } 

Perhaps the easiest way to do this will not throw an exception :

 for (int i = list.size()-1; i >= 0; i--) { Person o = list.get(i); if (o.isMarkedForDeletion()) { list.remove(i); } else { o.update(); } } 
+3
source

Just a wild assumption due to the absence of any code fragments, but most likely your rendering iterates through an ArrayList in a Swing thread, while another thread (a timer, I think?) Is trying to remove a person from the list.

If this is the case, one way is to force Swing to remove the person from the list (between the two visualizations) as:

 // peopleArray and personInstance should be final Runnable removePersonTask = new Runnable() { public void run() { peopleArray.remove(personInstance). } }; SwingUtilities.invokeLater(removePersonTask). 
+1
source

One of the most common causes of this problem is that you cannot change the ArrayList during retry.

In addition, since you have a GUI, you have at least two threads. Swing and AWT work on a separate branch. Therefore, if the GUI accesses the ArrayList directly, there may be some problems.

But without code it is impossible to say exactly what the problem is or may be.

0
source

All Articles