Вот ситуация, в которой мы должны развиваться.
У нас будет рой идентификаторов, которые будут вставлены непрерывно в коллекцию одним автором. Цель состоит в том, чтобы предупредить клиентов об этих конкретных идентификаторах.
С этой целью поток расписания будет проходить через эту коллекцию, сопоставлять идентификаторы и «перезагружать» коллекцию для опорожнения после нее.
Я намеревался использовать ConcurrentLinkedQueue для этого.
Хотя это сделает его потокобезопасным, есть возможность «сбросить» очистку некоторых идентификаторов, которые еще не были предупреждены.
Что было бы лучшим способом?поточно-безопасная коллекция для магазина и вперед
ответ
Ваша резьба вашего коллатера должна удалять каждую запись из очереди, когда она обрабатывает ее. Если вы это сделаете, нет необходимости перезагружать очередь, и ваша проблема с потерянными уведомлениями не возникает.
(Если это не имеет смысла для вас, есть, скорее всего, то, что вы не объясняя ясно. Попробуйте добавить некоторый пример кода ...)
Возможность «перезагрузки» очистки от некоторых идентификаторов является не только проблема, поэтому для того, что вы можете сделать, это:
в графике потока,
Сначала получите текущий размер/нет идентификаторов, находящихся в очереди на этой конкретной времени в локальной переменной " размер ", потому что он будет меняться при вставке нового элемента. Затем итерация на ConcurrentLinkedQueue до этого размер, , итерация удаления/опроса элементов из ConcurrentLinkedQueue для сбора идентификаторов.
Таким образом, вам не нужно перезагружать ConcurrentLinkedQueue.
Проще вы можете сохранить это, тем меньше будет ошибкой.
Я создал бы контейнер для управления вашей коллекцией идентификаторов, подвергая только две операции, которые вам нужны.
Ваш поток записи должен добавлять записи в коллекцию, а поток расписания должен собирать их партиями. Стратегия копирования на чтение потребует лишь нескольких строк:
import java.util.ArrayList;
import java.util.List;
public class IdList<T> {
private ArrayList<T> entries = new ArrayList<>();
/**
* Add a notification ID to the collection.
*/
public synchronized void add(T entry) {
entries.add(entry);
}
/**
* Remove the next batch of notification IDs from the collection.
*/
public synchronized List<T> drain() {
ArrayList<T> current = entries;
entries = new ArrayList<>();
return current;
}
}