РЕШЕНИЕ 1:
Просто имейте в виду, что во время процесса итерации ваш ключевой слушатель будет заблокирован (это также означает, что ваш итератор работает со старыми данными, как в решении 2).
Если вы используете ArrayList, сделайте следующее:
List list = Collections.synchronizedList(new ArrayList());
И используйте этот list
объект везде. Вы должны импортировать
import java.util.Collections;
Я согласен с @msandiford, добавляющим, как повторять ....
while(some_condition) {
do something
synchronized(list) {
Iterator i = list.iterator();
while (i.hasNext())
do_something_with(i.next());
}
do something else
}
Это быстрое решение, если у вас есть внешний цикл, в котором вы выполняете итерацию. Так что вы находитесь вне блока synchronized
на некоторое время, чтобы KeyListener
мог добавить в список массивов.
РЕШЕНИЕ 2:
Если вы хотите использовать COW, просто имейте в виду, что всякий раз, когда происходит операция добавления / обновления, он создаст копию нижележащей коллекции, и ваш итератор не увидит изменения. Но ключевой слушатель НЕ БУДЕТ заблокирован (но с этого момента будет создана новая копия).
import java.util.concurrent.CopyOnWriteArrayList;
List list = new CopyOnWriteArrayList<your_object_type>();
Для итерации:
while(some_condition) {
do something
Iterator i = list.iterator();
while (i.hasNext())
do_something_with(i.next());
do something else
}
РЕШЕНИЕ 3:
Это будет небольшое изменение дизайна. Это похоже на Решение 2, но имеет смысл, только если вы выполняете только операции добавления. Так что вы можете создать еще один временный шаблон List
и добавить в этот список Keylistener
. И как только ваша итерация завершится, сделайте блок synchronized
и переместите все объекты из temp List
в List
, который вы используете для итерации. Это НЕ БУДЕТ блокировать ваш KeyListener, но итератор увидит старые данные, как в решении 2. Возможно, он будет иметь лучшую производительность по сравнению с решением 2.
Так что выбирайте решение, которое имеет смысл для вашего дизайна.
Ref:
Коллекции Java
КПС