Большая проблема, насколько я понимаю, состоит в том, как позволить определенным элементам истечь через некоторое время. У меня было похожее требование, и я создал класс сообщений, в котором реализован интерфейс Delayed Interface . Этот класс содержал все, что мне было нужно для сообщения, и (через интерфейс Delayed) сообщал мне, когда оно истекло.
Я использовал экземпляры этого объекта в параллельной коллекции, вы можете использовать ConcurrentMap , потому что это позволит вам вводить эти объекты с помощью целочисленного ключа.
Время от времени я собирал коллекцию, убирая предметы, задержка которых прошла. Мы проверяем срок действия с помощью метода getDelay интерфейса Delayed:
message.getDelay(TimeUnit.MILLISECONDS);
Я использовал обычный поток, который некоторое время спал, а затем собирал устаревшие элементы. В моих требованиях не было важно, чтобы элементы были удалены, как только истек срок их задержки. Кажется, у вас есть аналогичная гибкость.
Если вам нужно было удалить элементы, как только истечет время их задержки, тогда вместо того, чтобы спать в течение заданного периода времени в вашем потоке, вы будете спать в ожидании задержки сообщения, которое истечет первым.
Вот мой класс отложенных сообщений:
class DelayedMessage implements Delayed {
long endOfDelay;
Date requestTime;
String message;
public DelayedMessage(String m, int delay) {
requestTime = new Date();
endOfDelay = System.currentTimeMillis()
+ delay;
this.message = m;
}
public long getDelay(TimeUnit unit) {
long delay = unit.convert(
endOfDelay - System.currentTimeMillis(),
TimeUnit.MILLISECONDS);
return delay;
}
public int compareTo(Delayed o) {
DelayedMessage that = (DelayedMessage) o;
if (this.endOfDelay < that.endOfDelay) {
return -1;
}
if (this.endOfDelay > that.endOfDelay) {
return 1;
}
return this.requestTime.compareTo(that.requestTime);
}
@Override
public String toString() {
return message;
}
}