
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}
~~~
- 線程
- 1.進程和線程-鎖與信號量
- 2.Thread類線程狀態轉換
- 2.并發與并行-同步與異步
- 4.線程池
- 5.對象級別與類級別的同步鎖
- 6.創建線程的四種方式
- 7.臨界區-阻塞-活鎖-死鎖
- 2.JMM多線程模型
- JUC
- BlockingQueue
- ArrayBlockingQueue
- DelayQueue
- LinkedBlockingQueue
- PriorityBlockingQueue
- SynchronousQueue
- BlockingDeque
- ConcurrentHashMap
- CountDownLatch
- CyclicBarrier
- Exchanger
- AtomicInteger
- Lock
- Condition
- ReentrantLock讀寫鎖
- StampedLock
- Semaphore