BlockingQueue как контейнер, который не допускает дублирование
Я хочу потокобезопасный контейнер, который блокирует вызывающего, пока элемент не станет доступным. Элементы будут добавляться со скоростью 1000 с в секунду в этот контейнер, но не будут израсходованы с той же скоростью. Поэтому я хочу, чтобы контейнер запрещал дубликаты. Я написал очень простую оболочку для LinkedBlockingQueue, но вскоре понял, что воссоздал классический тупик производитель-потребитель. Вот что я написал:
public class ActivityListener {
private final BlockingQueue<ID> activeItems = new LinkedBlockingQueue<>();
public synchronized ID take() throws InterruptedException {
return activeItems.take();
}
public synchronized void registerActivity(final ID item) {
if (!activeItems.contains(item)) {
activeItems.add(item);
}
}
public synchronized boolean isItemActive(final ID item) {
return activeItems.contains(item);
}
}
Я не смог найти надежного решения своей проблемы и был бы признателен за любую помощь.
1 ответ
Переопределите методы add() и put() любой реализации BlockingQueue, чтобы сначала проверить, находится ли элемент уже в очереди.
Что-то вроде -
@Override
public boolean add(T obj) {
if (contains(obj))
return true;
return super.add(obj);
}