DelayQueue 學習

DelayQueue 學習

介紹

jdk裏面的解釋是:

* An unbounded {@linkplain BlockingQueue blocking queue} of
 * {@code Delayed} elements, in which an element can only be taken
 * when its delay has expired.  The <em>head</em> of the queue is that
 * {@code Delayed} element whose delay expired furthest in the
 * past.  If no delay has expired there is no head and {@code poll}
 * will return {@code null}. Expiration occurs when an element's
 * {@code getDelay(TimeUnit.NANOSECONDS)} method returns a value less
 * than or equal to zero.  Even though unexpired elements cannot be
 * removed using {@code take} or {@code poll}, they are otherwise
 * treated as normal elements. For example, the {@code size} method
 * returns the count of both expired and unexpired elements.
 * This queue does not permit null elements.
 *
 * <p>This class and its iterator implement all of the
 * <em>optional</em> methods of the {@link Collection} and {@link
 * Iterator} interfaces.  The Iterator provided in method {@link
 * #iterator()} is <em>not</em> guaranteed to traverse the elements of
 * the DelayQueue in any particular order.

大概說: delayQueue是一個無界的帶延遲的阻塞隊列, 在delayQueue裏元素,只有延遲時間過期後纔可以被取出來.

隊列的頂端的元素是延遲時間最長的. 如果沒有延遲,頭部就沒有元素, poll的結果也就是null; 延遲的判斷是根據 “delayed”元素對象 調用 getDelay(TimeUnit.NANOSECONDS) 的方法返回值是否小於或者等於0; 雖然未到期的元素不能通過take 或者 poll 刪除, 但是仍然可以當做普通元素對象對待. 例如: size()方法返回所有元素的和(無論是否到期的元素). delayQueue不允許空元素. 添加null的元素將有NullpointException 拋出.

delayQueue它的迭代器,並沒有按特定的順序規則排序遍歷.

使用場景

delayQueue 可以使用在很多的併發,帶有延遲操作的工作中,也可以用在特殊的生產者-消費者模式上

  1. 超時任務處理上
  2. 延遲操作和清理過期數據業務上

使用方式

  • 創建延遲對象通過繼承Delayed接口
  • 重新getDelay,compareTo 方法

代碼示例


import java.util.Random;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class DelayTaskTester {

    private DelayQueue<DelayTask> delayQueue = new DelayQueue<DelayTask>();


    public static void main(String args[]) {
        DelayTaskTester tester = new DelayTaskTester();

        ExecutorService executorService = Executors.newFixedThreadPool(2, new ThreadFactory() {

            @Override
            public Thread newThread(Runnable r) {
                Thread t = new Thread(r);
                t.setDaemon(true);
                return t;
            }
        });

        executorService.submit(tester.new DelayTaskCustomer());
        executorService.submit(tester.new DelayTaskCustomer());

        Random random = new Random();

        long startTime = System.currentTimeMillis();

        for (int i = 0; i < 100; i++) {
            tester.delayQueue.offer(new DelayTask(random.nextInt(20 * 1000), startTime));
        }

        try {
            Thread.sleep(21 * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        executorService.shutdown();

    }

    class DelayTaskCustomer implements Runnable {

        @Override
        public void run() {

            while (true) {
                try {
                    DelayTask delayTask = delayQueue.take();

                    delayTask.print();

                } catch (Throwable e) {
                    e.printStackTrace();
                }
            }

        }

    }

}

import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

public class DelayTask implements Delayed {


    // 
    private final long timeStamp;

    // 記錄開始時間
    private final long startTime;

    private final long delayTime;

    public DelayTask (final long delayTime, final long startTime) {
        this.delayTime = delayTime;
        this.timeStamp = System.currentTimeMillis();

        this.startTime = startTime;
    }

    public long getExpectTime() {
        return timeStamp + delayTime;
    }

    @Override
    public int compareTo(Delayed o) {
        if (this.getExpectTime() > ((DelayTask) o).getExpectTime()) {
            return 1;
        } else if (this.getExpectTime() < ((DelayTask) o).getExpectTime()) {
            return -1;
        } 

        return 0;
    }

    @Override
    public long getDelay(TimeUnit unit) {

        return unit.convert((this.timeStamp + delayTime) - System.currentTimeMillis(), TimeUnit.NANOSECONDS);
    }

    /*
     */
    public void print() {
        long now = System.currentTimeMillis();
        long realDelayTime = now - this.timeStamp;
        long Deviation  = realDelayTime - this.delayTime;

        System.out.println(Thread.currentThread().getName() +"--延遲時間是:" 
                + this.delayTime +"..真實延遲時間.......:" + realDelayTime + "......誤差時間(單位毫秒)..::" +
                Deviation + "此時完成任務時間共經歷時間: " + (now - startTime));
    }
}

測試結果

pool-1-thread-1--延遲時間是:610..真實延遲時間.......:610......誤差時間(單位毫秒)..::0此時完成任務時間共經歷時間: 610
pool-1-thread-2--延遲時間是:1000..真實延遲時間.......:1001......誤差時間(單位毫秒)..::1此時完成任務時間共經歷時間: 1001
pool-1-thread-1--延遲時間是:1115..真實延遲時間.......:1127......誤差時間(單位毫秒)..::12此時完成任務時間共經歷時間: 1127
pool-1-thread-1--延遲時間是:1146..真實延遲時間.......:1158......誤差時間(單位毫秒)..::12此時完成任務時間共經歷時間: 1158
pool-1-thread-1--延遲時間是:1150..真實延遲時間.......:1158......誤差時間(單位毫秒)..::8此時完成任務時間共經歷時間: 1158
pool-1-thread-1--延遲時間是:1170..真實延遲時間.......:1174......誤差時間(單位毫秒)..::4此時完成任務時間共經歷時間: 1174
pool-1-thread-1--延遲時間是:1307..真實延遲時間.......:1314......誤差時間(單位毫秒)..::7此時完成任務時間共經歷時間: 1314
pool-1-thread-2--延遲時間是:1505..真實延遲時間.......:1518......誤差時間(單位毫秒)..::13此時完成任務時間共經歷時間: 1518
pool-1-thread-2--延遲時間是:1630..真實延遲時間.......:1644......誤差時間(單位毫秒)..::14此時完成任務時間共經歷時間: 1644
pool-1-thread-2--延遲時間是:2084..真實延遲時間.......:2096......誤差時間(單位毫秒)..::12此時完成任務時間共經歷時間: 2096
pool-1-thread-2--延遲時間是:2155..真實延遲時間.......:2160......誤差時間(單位毫秒)..::5此時完成任務時間共經歷時間: 2160
pool-1-thread-2--延遲時間是:2432..真實延遲時間.......:2442......誤差時間(單位毫秒)..::10此時完成任務時間共經歷時間: 2442
pool-1-thread-1--延遲時間是:2557..真實延遲時間.......:2567......誤差時間(單位毫秒)..::10此時完成任務時間共經歷時間: 2567
pool-1-thread-1--延遲時間是:2605..真實延遲時間.......:2614......誤差時間(單位毫秒)..::9此時完成任務時間共經歷時間: 2614
pool-1-thread-2--延遲時間是:2681..真實延遲時間.......:2692......誤差時間(單位毫秒)..::11此時完成任務時間共經歷時間: 2692
pool-1-thread-2--延遲時間是:2721..真實延遲時間.......:2723......誤差時間(單位毫秒)..::2此時完成任務時間共經歷時間: 2723
pool-1-thread-2--延遲時間是:2913..真實延遲時間.......:2927......誤差時間(單位毫秒)..::14此時完成任務時間共經歷時間: 2927
pool-1-thread-1--延遲時間是:3058..真實延遲時間.......:3067......誤差時間(單位毫秒)..::9此時完成任務時間共經歷時間: 3067
pool-1-thread-1--延遲時間是:3273..真實延遲時間.......:3287......誤差時間(單位毫秒)..::14此時完成任務時間共經歷時間: 3287
pool-1-thread-1--延遲時間是:3567..真實延遲時間.......:3568......誤差時間(單位毫秒)..::1此時完成任務時間共經歷時間: 3568
pool-1-thread-1--延遲時間是:3747..真實延遲時間.......:3757......誤差時間(單位毫秒)..::10此時完成任務時間共經歷時間: 3757
pool-1-thread-1--延遲時間是:4367..真實延遲時間.......:4367......誤差時間(單位毫秒)..::0此時完成任務時間共經歷時間: 4367
pool-1-thread-2--延遲時間是:4815..真實延遲時間.......:4821......誤差時間(單位毫秒)..::6此時完成任務時間共經歷時間: 4821
pool-1-thread-2--延遲時間是:4826..真實延遲時間.......:4853......誤差時間(單位毫秒)..::27此時完成任務時間共經歷時間: 4853
pool-1-thread-1--延遲時間是:4963..真實延遲時間.......:4977......誤差時間(單位毫秒)..::14此時完成任務時間共經歷時間: 4977
pool-1-thread-1--延遲時間是:5050..真實延遲時間.......:5055......誤差時間(單位毫秒)..::5此時完成任務時間共經歷時間: 5055
pool-1-thread-1--延遲時間是:5069..真實延遲時間.......:5071......誤差時間(單位毫秒)..::2此時完成任務時間共經歷時間: 5071
pool-1-thread-2--延遲時間是:5192..真實延遲時間.......:5197......誤差時間(單位毫秒)..::5此時完成任務時間共經歷時間: 5197
pool-1-thread-2--延遲時間是:5794..真實延遲時間.......:5806......誤差時間(單位毫秒)..::12此時完成任務時間共經歷時間: 5806
pool-1-thread-1--延遲時間是:5881..真實延遲時間.......:5886......誤差時間(單位毫秒)..::5此時完成任務時間共經歷時間: 5886
pool-1-thread-1--延遲時間是:6318..真實延遲時間.......:6324......誤差時間(單位毫秒)..::6此時完成任務時間共經歷時間: 6324
pool-1-thread-1--延遲時間是:6410..真實延遲時間.......:6418......誤差時間(單位毫秒)..::8此時完成任務時間共經歷時間: 6418
pool-1-thread-1--延遲時間是:6415..真實延遲時間.......:6418......誤差時間(單位毫秒)..::3此時完成任務時間共經歷時間: 6418
pool-1-thread-2--延遲時間是:6584..真實延遲時間.......:6589......誤差時間(單位毫秒)..::5此時完成任務時間共經歷時間: 6589
pool-1-thread-1--延遲時間是:7040..真實延遲時間.......:7044......誤差時間(單位毫秒)..::4此時完成任務時間共經歷時間: 7044
pool-1-thread-2--延遲時間是:7090..真實延遲時間.......:7091......誤差時間(單位毫秒)..::1此時完成任務時間共經歷時間: 7091
pool-1-thread-1--延遲時間是:7126..真實延遲時間.......:7138......誤差時間(單位毫秒)..::12此時完成任務時間共經歷時間: 7138
pool-1-thread-1--延遲時間是:7535..真實延遲時間.......:7545......誤差時間(單位毫秒)..::10此時完成任務時間共經歷時間: 7545
pool-1-thread-1--延遲時間是:7649..真實延遲時間.......:7655......誤差時間(單位毫秒)..::6此時完成任務時間共經歷時間: 7655
pool-1-thread-1--延遲時間是:8097..真實延遲時間.......:8109......誤差時間(單位毫秒)..::12此時完成任務時間共經歷時間: 8109
pool-1-thread-2--延遲時間是:8478..真實延遲時間.......:8487......誤差時間(單位毫秒)..::9此時完成任務時間共經歷時間: 8487
pool-1-thread-1--延遲時間是:8747..真實延遲時間.......:8752......誤差時間(單位毫秒)..::5此時完成任務時間共經歷時間: 8752
pool-1-thread-2--延遲時間是:8832..真實延遲時間.......:8846......誤差時間(單位毫秒)..::14此時完成任務時間共經歷時間: 8846
pool-1-thread-2--延遲時間是:8876..真實延遲時間.......:8878......誤差時間(單位毫秒)..::2此時完成任務時間共經歷時間: 8878
pool-1-thread-2--延遲時間是:9088..真實延遲時間.......:9096......誤差時間(單位毫秒)..::8此時完成任務時間共經歷時間: 9096
pool-1-thread-2--延遲時間是:9211..真實延遲時間.......:9222......誤差時間(單位毫秒)..::11此時完成任務時間共經歷時間: 9222
pool-1-thread-2--延遲時間是:9648..真實延遲時間.......:9661......誤差時間(單位毫秒)..::13此時完成任務時間共經歷時間: 9661
pool-1-thread-2--延遲時間是:10020..真實延遲時間.......:10021......誤差時間(單位毫秒)..::1此時完成任務時間共經歷時間: 10021
pool-1-thread-2--延遲時間是:10198..真實延遲時間.......:10208......誤差時間(單位毫秒)..::10此時完成任務時間共經歷時間: 10208
pool-1-thread-1--延遲時間是:10630..真實延遲時間.......:10631......誤差時間(單位毫秒)..::1此時完成任務時間共經歷時間: 10631
pool-1-thread-1--延遲時間是:11155..真實延遲時間.......:11163......誤差時間(單位毫秒)..::8此時完成任務時間共經歷時間: 11163
pool-1-thread-1--延遲時間是:11244..真實延遲時間.......:11257......誤差時間(單位毫秒)..::13此時完成任務時間共經歷時間: 11257
pool-1-thread-1--延遲時間是:11357..真實延遲時間.......:11367......誤差時間(單位毫秒)..::10此時完成任務時間共經歷時間: 11367
pool-1-thread-1--延遲時間是:11459..真實延遲時間.......:11461......誤差時間(單位毫秒)..::2此時完成任務時間共經歷時間: 11461
pool-1-thread-1--延遲時間是:11468..真實延遲時間.......:11476......誤差時間(單位毫秒)..::8此時完成任務時間共經歷時間: 11476
pool-1-thread-1--延遲時間是:11719..真實延遲時間.......:11726......誤差時間(單位毫秒)..::7此時完成任務時間共經歷時間: 11726
pool-1-thread-1--延遲時間是:11722..真實延遲時間.......:11726......誤差時間(單位毫秒)..::4此時完成任務時間共經歷時間: 11726
pool-1-thread-2--延遲時間是:11820..真實延遲時間.......:11821......誤差時間(單位毫秒)..::1此時完成任務時間共經歷時間: 11821
pool-1-thread-1--延遲時間是:11906..真實延遲時間.......:11915......誤差時間(單位毫秒)..::9此時完成任務時間共經歷時間: 11915
pool-1-thread-1--延遲時間是:12208..真實延遲時間.......:12213......誤差時間(單位毫秒)..::5此時完成任務時間共經歷時間: 12213
pool-1-thread-2--延遲時間是:12404..真實延遲時間.......:12415......誤差時間(單位毫秒)..::11此時完成任務時間共經歷時間: 12415
pool-1-thread-1--延遲時間是:12727..真實延遲時間.......:12728......誤差時間(單位毫秒)..::1此時完成任務時間共經歷時間: 12728
pool-1-thread-2--延遲時間是:12955..真實延遲時間.......:12964......誤差時間(單位毫秒)..::9此時完成任務時間共經歷時間: 12964
pool-1-thread-1--延遲時間是:13201..真實延遲時間.......:13214......誤差時間(單位毫秒)..::13此時完成任務時間共經歷時間: 13214
pool-1-thread-1--延遲時間是:13440..真實延遲時間.......:13449......誤差時間(單位毫秒)..::9此時完成任務時間共經歷時間: 13449
pool-1-thread-1--延遲時間是:13788..真實延遲時間.......:13793......誤差時間(單位毫秒)..::5此時完成任務時間共經歷時間: 13793
pool-1-thread-2--延遲時間是:13814..真實延遲時間.......:13824......誤差時間(單位毫秒)..::10此時完成任務時間共經歷時間: 13824
pool-1-thread-2--延遲時間是:14016..真實延遲時間.......:14028......誤差時間(單位毫秒)..::12此時完成任務時間共經歷時間: 14028
pool-1-thread-1--延遲時間是:14191..真實延遲時間.......:14201......誤差時間(單位毫秒)..::10此時完成任務時間共經歷時間: 14201
pool-1-thread-2--延遲時間是:14265..真實延遲時間.......:14279......誤差時間(單位毫秒)..::14此時完成任務時間共經歷時間: 14279
pool-1-thread-1--延遲時間是:14422..真實延遲時間.......:14436......誤差時間(單位毫秒)..::14此時完成任務時間共經歷時間: 14436
pool-1-thread-1--延遲時間是:14525..真實延遲時間.......:14529......誤差時間(單位毫秒)..::4此時完成任務時間共經歷時間: 14529
pool-1-thread-1--延遲時間是:14669..真實延遲時間.......:14670......誤差時間(單位毫秒)..::1此時完成任務時間共經歷時間: 14670
pool-1-thread-1--延遲時間是:14718..真實延遲時間.......:14732......誤差時間(單位毫秒)..::14此時完成任務時間共經歷時間: 14732
pool-1-thread-1--延遲時間是:14886..真實延遲時間.......:14889......誤差時間(單位毫秒)..::3此時完成任務時間共經歷時間: 14889
pool-1-thread-1--延遲時間是:14929..真實延遲時間.......:14937......誤差時間(單位毫秒)..::8此時完成任務時間共經歷時間: 14937
pool-1-thread-1--延遲時間是:15041..真實延遲時間.......:15046......誤差時間(單位毫秒)..::5此時完成任務時間共經歷時間: 15046
pool-1-thread-1--延遲時間是:15330..真實延遲時間.......:15344......誤差時間(單位毫秒)..::14此時完成任務時間共經歷時間: 15344
pool-1-thread-1--延遲時間是:15362..真實延遲時間.......:15375......誤差時間(單位毫秒)..::13此時完成任務時間共經歷時間: 15375
pool-1-thread-1--延遲時間是:15812..真實延遲時間.......:15813......誤差時間(單位毫秒)..::1此時完成任務時間共經歷時間: 15813
pool-1-thread-1--延遲時間是:16022..真實延遲時間.......:16032......誤差時間(單位毫秒)..::10此時完成任務時間共經歷時間: 16032
pool-1-thread-2--延遲時間是:16056..真實延遲時間.......:16063......誤差時間(單位毫秒)..::7此時完成任務時間共經歷時間: 16063
pool-1-thread-2--延遲時間是:16095..真實延遲時間.......:16095......誤差時間(單位毫秒)..::0此時完成任務時間共經歷時間: 16095
pool-1-thread-1--延遲時間是:16248..真實延遲時間.......:16251......誤差時間(單位毫秒)..::3此時完成任務時間共經歷時間: 16251
pool-1-thread-1--延遲時間是:16313..真實延遲時間.......:16314......誤差時間(單位毫秒)..::1此時完成任務時間共經歷時間: 16314
pool-1-thread-2--延遲時間是:16318..真實延遲時間.......:16329......誤差時間(單位毫秒)..::11此時完成任務時間共經歷時間: 16329
pool-1-thread-1--延遲時間是:16697..真實延遲時間.......:16706......誤差時間(單位毫秒)..::9此時完成任務時間共經歷時間: 16706
pool-1-thread-2--延遲時間是:16901..真實延遲時間.......:16909......誤差時間(單位毫秒)..::8此時完成任務時間共經歷時間: 16909
pool-1-thread-1--延遲時間是:17252..真實延遲時間.......:17253......誤差時間(單位毫秒)..::1此時完成任務時間共經歷時間: 17253
pool-1-thread-2--延遲時間是:17322..真實延遲時間.......:17332......誤差時間(單位毫秒)..::10此時完成任務時間共經歷時間: 17332
pool-1-thread-1--延遲時間是:17475..真實延遲時間.......:17489......誤差時間(單位毫秒)..::14此時完成任務時間共經歷時間: 17489
pool-1-thread-2--延遲時間是:17478..真實延遲時間.......:17489......誤差時間(單位毫秒)..::11此時完成任務時間共經歷時間: 17489
pool-1-thread-1--延遲時間是:17686..真實延遲時間.......:17692......誤差時間(單位毫秒)..::6此時完成任務時間共經歷時間: 17692
pool-1-thread-1--延遲時間是:17936..真實延遲時間.......:17942......誤差時間(單位毫秒)..::6此時完成任務時間共經歷時間: 17942
pool-1-thread-1--延遲時間是:17986..真實延遲時間.......:17989......誤差時間(單位毫秒)..::3此時完成任務時間共經歷時間: 17989
pool-1-thread-1--延遲時間是:18114..真實延遲時間.......:18114......誤差時間(單位毫秒)..::0此時完成任務時間共經歷時間: 18114
pool-1-thread-2--延遲時間是:18158..真實延遲時間.......:18162......誤差時間(單位毫秒)..::4此時完成任務時間共經歷時間: 18162
pool-1-thread-1--延遲時間是:18565..真實延遲時間.......:18567......誤差時間(單位毫秒)..::2此時完成任務時間共經歷時間: 18567
pool-1-thread-1--延遲時間是:18863..真實延遲時間.......:18867......誤差時間(單位毫秒)..::4此時完成任務時間共經歷時間: 18867
pool-1-thread-1--延遲時間是:19952..真實延遲時間.......:19952......誤差時間(單位毫秒)..::0此時完成任務時間共經歷時間: 19952
發佈了49 篇原創文章 · 獲贊 13 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章