SOLUTION 1:
Just keep in mind that your listener will be blocked during the iteration process (this also means that your iterator is running on old data, as in solution 2).
If you are using an ArrayList, follow these steps:
List list = Collections.synchronizedList(new ArrayList());
And each time use this list
object. You must import
import java.util.Collections;
I agree with @msandiford Adding how to iterate ....
while(some_condition) { do something synchronized(list) { Iterator i = list.iterator(); while (i.hasNext()) do_something_with(i.next()); } do something else }
This is a quick fix if you have an outer loop in which you iterate. This way, you have not used the synchronized
block for some time, so that the KeyListener
can be added to the list of arrays.
SOLUTION 2:
If you want to use COW, just keep in mind that whenever an add / update operation occurs, it will make a copy of the collection below and your iterator will not see the change. But the main listener will NOT be blocked (but at this moment a new copy will be created under it).
import java.util.concurrent.CopyOnWriteArrayList; List list = new CopyOnWriteArrayList<your_object_type>();
Iteration:
while(some_condition) { do something Iterator i = list.iterator(); while (i.hasNext()) do_something_with(i.next()); do something else }
SOLUTION 3:
This will be a minor design change. This is similar to solution 2, but only makes sense if you are only performing add operations. So what you can do is create another temp list
and add it to this list in KeyListener
. And as soon as your iteration is done through the synchronized
block and move all the objects from temp list
to list
that you use for iteration. This does NOT block your KeyListener, but the iterator will see the old data, as in solution 2. It can have better performance compared to solution 2.
So, choose a solution that makes sense for your design.
Ref:
Java COW Collections