DelayQueue 是BlockingQueue介面的實現類,它根據"延時時間"來確定佇列內的元素的處理優先順序(即根據佇列元素的“延時時間”進行排序)。另一層含義是隻有那些超過“延時時間”的元素才能從佇列裡面被拿出來進行處理。
- DelayQueue 佇列將阻止其元素物件從佇列中被取出,直到達到為元素物件設定的延遲時間。DelayQueue 在佇列的頭部儲存最近過期的元素,如果佇列內沒有元素過期,使用poll()方法獲取佇列內的元素將會返回null。
- DelayQueue 類及其迭代器實現了Collection和Iterator介面的所有可選方法,但迭代器方法
iterator()
不能保證以特定的順序遍歷DelayQueue的元素。
- DelayQueue 不接收null元素,DelayQueue 只接受那些實現了java.util.concurrent.Delayed介面的物件,並將其放入佇列內。DelayQueue 通過呼叫元素物件的getDelay(TimeUnit) 方法獲取該元素剩餘的“延遲時間”。getDelay()的 TimeUnit時間單位是一個列舉型別 : DAYS(天), HOURS(小時), MINUTES(分鐘), SECONDS(秒), MILLISECONDS(毫秒), MICROSECONDS(微妙), NANOSECONDS(納秒)
public interface Delayed extends Comparable{
long getDelay(TimeUnit unit);
}
下面我們就寫一個java Class實現Delayed 介面,只有實現了Delayed 介面的類物件才能放入DelayQueue。因為Delayed介面繼承自Comparable介面,所以我們必須實現getDelay方法和compareTo方法。
class DelayObject implements Delayed {
private String name;
private long time; //延時時間
public DelayObject(String name, long delayTime) {
this.name = name;
this.time = System.currentTimeMillis() + delayTime;
}
@Override
public long getDelay(TimeUnit unit) {
long diff = time - System.currentTimeMillis();
return unit.convert(diff, TimeUnit.MILLISECONDS);
}
@Override
public int compareTo(Delayed obj) {
if (this.time < ((DelayObject)obj).time) {
return -1;
}
if (this.time > ((DelayObject)obj).time) {
return 1;
}
return 0;
}
@Override
public String toString() {
Date date = new Date(time);
SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return "\nDelayObject:{"
+ "name=" + name
+ ", time=" + sd.format(date)
+ "}";
}
}
測試延時佇列DelayQueue的使用效果
public class DelayQueueTest {
@Test
void testDelayObject() throws InterruptedException {
//例項化一個DelayQueue
BlockingQueue<DelayObject> DQ = new DelayQueue<>();
//向DelayQueue新增四個元素物件,注意延時時間不同
DQ.add(new DelayObject("A", 1000 * 10)); //延時10秒
DQ.add(new DelayObject("B", 4000 * 10)); //延時40秒
DQ.add(new DelayObject("C", 3000 * 10)); //延時30秒
DQ.add(new DelayObject("D", 2000 * 10)); //延時20秒
SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//將物件從DelayQueue取出,注意取出的順序與延時時間有關
System.out.println( DQ.take()); //取出A
System.out.println( DQ.take()); //取出D
System.out.println( DQ.take()); //取出C
System.out.println( DQ.take()); //取出B
}
}
從下面的列印結果及上文的程式碼可以看出
- 佇列中元素放入的順序是A、B、C、D,取出的順序是A、D、C、B,這是因為佇列中的元素按照延時時間進行了排序。
- 另外我們可以看到,每隔10秒才可以從佇列中取出一個元素,這是因為只有超過“延時時間”的元素才能從佇列裡面被拿出來。而我們設定的延時時間是10s、20s、30s、40s。
DelayObject:{name=A, time=2021-03-23 14:14:20}
DelayObject:{name=D, time=2021-03-23 14:14:30}
DelayObject:{name=C, time=2021-03-23 14:14:40}
DelayObject:{name=B, time=2021-03-23 14:14:50}
歡迎關注我的部落格,裡面有很多精品合集
- 本文轉載註明出處(必須帶連線,不能只轉文字):字母哥部落格。
覺得對您有幫助的話,幫我點贊、分享!您的支援是我不竭的創作動力! 。另外,筆者最近一段時間輸出瞭如下的精品內容,期待您的關注。