https://www.cnblogs.com/hhan/p/10678466.html
展開 文章目錄 [一] 簡介 [二] DelayQueue 繼承體系 1. 核心方法 take() put(E) offer(E) poll() peek() size() clear() [三] 使用 DelayQueue 准備 Delayed 的實現類 1. 構造方法 [一] 簡介 注釋來自java api Delayed 元素的一個無界阻塞隊列,只有在延遲期滿時才能從中提取元素。該隊列的頭部 是延遲期滿后保存時間最長的 Delayed 元素。如果延遲都還沒有期滿,則隊列沒有頭部,並且 poll 將返回 null。當一個元素的 getDelay(TimeUnit.NANOSECONDS) 方法返回一個小於等於 0 的值時,將發生到期。即使無法使用 take 或 poll 移除未到期的元素,也不會將這些元素作為正常元素對待。例如,size 方法同時返回到期和未到期元素的計數。此隊列不允許使用 null 元素。 [二] DelayQueue 繼承體系 public class DelayQueue<E extends Delayed>extends AbstractQueue<E>implements BlockingQueue<E> 1 1. 核心方法 take() 獲取並移除此隊列的頭部,在可從此隊列獲得到期延遲的元素之前一直等待(如有必要)。 put(E) 將指定元素插入此延遲隊列。 offer(E) 將指定元素插入此延遲隊列。 poll() 獲取並移除此隊列的頭,如果此隊列不包含具有已到期延遲時間的元素,則返回 null。 peek() 獲取但不移除此隊列的頭部;如果此隊列為空,則返回 null。 size() 返回此 collection 中的元素數。 clear() 自動移除此延遲隊列的所有元素。 [三] 使用 DelayQueue 准備 Delayed 的實現類 DelayQueue<E extends Delayed> 使用這個超時隊列, 根據他的泛型限制類型, 他所存儲的元素必須是 Delayed 這個接口的子類; 因此我們必須先構造一個這樣的子類, 假設有一個定時任務 Task, 在設定時間然后從隊列取出執行他. 定時任務 Task /** * * 定時任務 */ public class Task { // 任務id private Integer id; // 任務名稱 private String name; // 執行時間 private Long time; public Task(Integer id, String name, Long time) { this.id = id; this.name = name; this.time = time; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Long getTime() { return time; } public void setTime(Long time) { this.time = time; } @Override public String toString() { return "Task [id=" + id + ", name=" + name + ", time=" + new Date(time).toString() + "]"; } } Delayed 實現類: 因為我們並不想改變 Task 的結構, 所以另外創建一個實現類 TaskDelayed public class TaskDelayed implements Delayed { // 任務 private Task task; public TaskDelayed(Task task) { super(); this.task = task; } public Task getTask() { return task; } @Override public int compareTo(Delayed o) { return (int) (this.getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS)); } @Override public long getDelay(TimeUnit unit) { long time = task.getTime(); long currentTime = System.currentTimeMillis(); return unit.convert(time - currentTime, TimeUnit.MILLISECONDS); } } 1. 構造方法 BlockingQueue<TaskDelayed> queue = new DelayQueue<>(); 1 put 與 take (一直阻塞直到完成操作為止) public static void main(String[] args) throws InterruptedException { BlockingQueue<TaskDelayed> queue = new DelayQueue<>(); queue.put(new TaskDelayed(new Task(5, "ssss", System.currentTimeMillis() + 9000L))); queue.put(new TaskDelayed(new Task(2, "ssss", System.currentTimeMillis() + 6000L))); queue.put(new TaskDelayed(new Task(3, "ssss", System.currentTimeMillis() + 7000L))); queue.put(new TaskDelayed(new Task(1, "ssss", System.currentTimeMillis() + 5000L))); queue.put(new TaskDelayed(new Task(4, "ssss", System.currentTimeMillis() + 8000L))); for(;;) { System.out.println(queue.take().getTask() + "----" + new Date()); } } 執行結果 Task [id=1, name=ssss, time=Wed Jan 23 14:09:12 CST 2019]----Wed Jan 23 14:09:12 CST 2019 Task [id=2, name=ssss, time=Wed Jan 23 14:09:13 CST 2019]----Wed Jan 23 14:09:13 CST 2019 Task [id=3, name=ssss, time=Wed Jan 23 14:09:14 CST 2019]----Wed Jan 23 14:09:14 CST 2019 Task [id=4, name=ssss, time=Wed Jan 23 14:09:15 CST 2019]----Wed Jan 23 14:09:15 CST 2019 Task [id=5, name=ssss, time=Wed Jan 23 14:09:16 CST 2019]----Wed Jan 23 14:09:16 CST 2019 這里取出的時間和系統當前時間一致, 因為我們指定了他取出的時間 關鍵方法在於 Delayed public interface Delayed extends Comparable<Delayed> { long getDelay(TimeUnit unit); } 具體實現: 返回與此對象相關的剩余延遲時間,以給定的時間單位表示。 @Override public long getDelay(TimeUnit unit) { long time = task.getTime(); long currentTime = System.currentTimeMillis(); return unit.convert(time - currentTime, TimeUnit.MILLISECONDS); } ———————————————— 版權聲明:本文為CSDN博主「程序猿-Jojo」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。 原文鏈接:https://blog.csdn.net/weixin_39554102/article/details/86608830