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