-1

I am making a particle emitter. Every "Rendered" object is stored in a HashSet, and when there's lots of particles on the screen, the console spits out concurrent modification exceptions. I usually have a short lifetime on these particles so they get deleted after several seconds, but I am sure this could potentially be a problem in the future. How can I fix this?

EDIT: Code:

public class UpdatedManager {
private static Set<Updated> updates = new HashSet<>();

private UpdatedManager() {}

public static Set<Updated> getUpdates() {
    return new HashSet<Updated>(updates);
}
public static boolean registerUpdated(Updated u) {
    return updates.add(u);
}
public static boolean unregisterUpdated(Updated u) {
    return updates.remove(u);
}
public static void update() {
    for (Updated up : new HashSet<Updated>(updates))
        up.update();
}
public static Set<GameObject> getGameObjects() {
    Set<GameObject> objs = new HashSet<>();
    for (Updated up : new HashSet<Updated>(updates)) {
        if (up instanceof GameObject)
            objs.add((GameObject) up);
    }
    return objs;
}
public static Set<GameObject> getGameObjectsByName(String name) {
    Set<GameObject> objs = new HashSet<>();
    for (GameObject go : new HashSet<GameObject>(getGameObjects())) {
        if (go.getName() != null && go.getName().equals(name))
            objs.add(go);
    }
    return objs;
}
public static Set<Particle> getParticles() {
    Set<Particle> parts = new HashSet<>();
    for (Updated up : new HashSet<Updated>(updates)) {
        if (up instanceof Particle)
            parts.add((Particle) up);
    }
    return parts;
}
}
MCMastery
  • 3,099
  • 2
  • 20
  • 43
  • 2
    ConcurrentModificationException usually happens when you are making changes to a set, like deleting elements, while at the same time iterating over the set. You need to redesign your approach to the problem. – Vincent Ramdhanie Dec 08 '14 at 22:50
  • Which line is the exception thrown on? – user253751 Dec 08 '14 at 23:14

2 Answers2

1

A ConcurrentModificationException means you modified the set while iterating over it. It does not mean the set is full.

For example, the following code will throw a ConcurrentModificationException:

Set<String> set = new HashSet<>();

set.add("Hello");

for(String s : set)
    set.add(s+" world");

Note that you are not guaranteed to get a ConcurrentModificationException, so you should avoid catching it. You should instead fix your code so that it doesn't cause the problem.

user253751
  • 57,427
  • 7
  • 48
  • 90
  • I loop through a copy of the set, not the actually set. – MCMastery Dec 08 '14 at 23:04
  • 1
    @MCMastery If you loop through a copy of the set (as in `for(String s : new HashSet<>(set))` then you don't get a ConcurrentModificationException (because you're not modifying the copy). You get a ConcurrentModificationException, therefore you are not looping through a copy of the set. – user253751 Dec 08 '14 at 23:06
  • Where it says the error occurs, it is a copy. I'll double check again – MCMastery Dec 08 '14 at 23:08
-1

What makes you think that the set is full?

Concurrent modification exceptions mean that the set is being accessed by different threads in an unsafe manner.

Try a synchronised set using the Collections utilities

HashSet hashSet = new HashSet();
Set set = Collections.synchronizedSet(hashSet);

or use the synchronized keyword for the method accessing the set.

dovidzeev
  • 27
  • 4
  • I downvoted this for suggesting that synchronizedSet will solve all the OP's problems, without knowing the root cause. synchronizedSet will not solve all ConcurrentModificationException problems. Even the ones cause by multithreading. – user253751 Dec 08 '14 at 23:07