Search code examples
javavectorconcurrencyconcurrentmodification

Java Concurrency Issues concerning Listeners


What is the best, or the common solution to concurrency concerning Java? I see a lot of solutions on this and other websites, but none of them work for my problem.

My problem is as follows: I have a vector of a class I wrote myself. (If this helps solving it I can just as easily make it an ArrayList or something like that) Now, on a very regular basis (up to thousands of times per second) I read all elements in this vector and manipulate them in some way. At the same time I add and remove elements bases on events in my MouseListener and my KeyListener (which is essential to the program). This of course gives me quite a few problems. I don't want to read the vector while adding or removing elements, because this would throw a java.util.ConcurrentModificationException. However, I can't really use a temporary vector to store these events because that would create the problem of clearing this vector while adding things to it. How do you get out of this mess?


Solution

  • You can wrap your Vector of items with a thread safe wrapper using java.util.Collections. There is a specific method for List i.e. synchronizedList but not for Vector. This only solves part of the problem by synchronizing all the public method calls, add() and remove() etc.

    private Collection<Thing> things =
             Collections.synchronizedCollection(new Vector<Thing>());
    

    (or for a List)

    private Collection<Thing> listeners =
           Collections.synchronizedList(new ArrayList<Thing>());
    

    You also need to protect your iteration... There are two ways to do this, either lock the collection whilst you iterate...

    synchronized (things) {
        for (Thing thing : things) {
    
        }
    }
    

    or take a copy and iterate over that...

    for (Thing thing : things.toArray(new MouseListener[]{})) {
    
    }