Очереди с задержкой - это потокобезопасные структуры данных, элементы которых можно извлекать после заданной задержки.
1- Как использовать очередь задержки?
В отличие от любых других очередей, очередь задержки принимает объекты классов, которые реализуют интерфейс Delayed, который также расширяет интерфейс Comparable, который вы можете увидеть ниже.
public interface Delayed extends Comparable<Delayed> { long getDelay(TimeUnit unit); } public interface Comparable<T> { public int compareTo(T o); }
Итак, когда вы создаете свой собственный объект, который будет помещен в отложенную очередь, вы реализуете эти методы. Давайте создадим наш собственный класс Delayed.
public class DelayedItem implements Delayed { private String name; private long startingTime; public DelayedItem(String name, long delay) { this.name = name; this.startingTime = System.currentTimeMillis() + delay; } public String getName() { return name; } @Override public long getDelay(TimeUnit unit) { long delay = startingTime - System.currentTimeMillis(); return unit.toMillis(delay); } @Override public int compareTo(Delayed o) { return Long.compare(startingTime, ((DelayedItem) o).startingTime); } }
В приведенном выше примере мы берем два параметра для инициализации объекта с задержкой. Первое - это имя, оно предназначено только для демонстрации и будет использоваться позже. Второй - задержка, после которой мы можем получить объект из очереди. Как вы заметили, мы создали поле startTime, используя заданную задержку и текущее время. В этом поле указано, что по истечении этого времени вы можете удалить этот объект из очереди. Затем мы реализовали методы getDelay и compareTo. getDelay просто возвращает задержку, как следует из его названия, а compareTo выполняет сравнение для сортировки объектов в очереди в соответствии с их временем, когда они могут быть удалены.
Теперь пришло время использовать наш отложенный элемент и очередь задержки.
public static void main(String[] args) { DelayQueue<DelayedItem> delayedItems = new DelayQueue<>(); DelayedItem delayedItem1 = new DelayedItem("item1", 1000); DelayedItem delayedItem2 = new DelayedItem("item2", 500); DelayedItem delayedItem3 = new DelayedItem("item3", 750); DelayedItem delayedItem4 = new DelayedItem("item3", 1250); delayedItems.add(delayedItem1); delayedItems.add(delayedItem2); delayedItems.add(delayedItem3); delayedItems.add(delayedItem4); while (!delayedItems.isEmpty()) { try { System.out.println(delayedItems.take().getName()); } catch (InterruptedException e) { e.printStackTrace(); } } }
Сначала мы создаем несколько элементов, каждый из которых имеет разные задержки, а затем помещаем их в очередь. Затем мы извлекаем элементы из очереди и выводим их имена в консоль. Выход будет
item2 item3 item1 item3
Как видите, item2 помещается в очередь как третий, но поскольку у него самая низкая задержка среди других элементов, он снимается первым, а остальные выстраиваются в очередь в соответствии с их задержками.
2- Когда использовать очередь задержки?
Очереди с задержкой могут использоваться где угодно в соответствии с потребностями, и они легко адаптируются к многопоточным средам, поскольку это потокобезопасная структура данных.
В этом руководстве я рассказал об очередях задержки и о том, как их использовать. Я надеюсь, тебе это нравится.