Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 406
Lara Avatar asked Apr 11 '26 16:04

Lara


2 Answers

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[]{})) {

}
like image 170
Adam Avatar answered Apr 13 '26 05:04

Adam


You want to use a CopyOnWriteArrayList. This is safe to use in multithreaded and concurrent programming environments.

When iterating over a CopyOnWriteArrayList you will not get ConcurrentModificationExceptions as any changes create a new array internally and do not affect the one being iterated over. It was pretty much designed to host a list of listeners.

This has the benefit of not needing any synchronisation when iterating, and has very short locked segments, iteration will never block!

like image 34
ggovan Avatar answered Apr 13 '26 05:04

ggovan