Mastering Delayed Task Scheduling in Java: From Quartz to Redis and RabbitMQ

This article explains the concept of delayed tasks, compares them with scheduled tasks, and evaluates multiple implementation strategies—including database polling, JDK DelayQueue, Netty HashedWheelTimer, Redis ZSET, Redis keyspace notifications, and RabbitMQ delayed queues—highlighting their advantages and drawbacks for order‑processing scenarios.

Su San Talks Tech
Su San Talks Tech
Su San Talks Tech
Mastering Delayed Task Scheduling in Java: From Quartz to Redis and RabbitMQ

In development, delayed tasks are needed for scenarios such as automatically canceling unpaid orders after 30 minutes or sending SMS 60 seconds after order creation.

Unlike scheduled tasks, delayed tasks have no fixed trigger time, no execution cycle, and usually handle a single event after a specific trigger.

Solution Analysis

(1) Database Polling

This approach scans the database at fixed intervals to find expired orders and updates or deletes them. It is simple and supports clustering but consumes a lot of memory, can cause high latency, and heavily loads the database when order volume is large.

(2) JDK DelayQueue

Uses the built‑in DelayQueue which only allows retrieval after the delay expires. Elements must implement Delayed. Example implementation OrderDelay and demo code are shown.

public class OrderDelay implements Delayed {
    private String orderId;
    private long timeout;
    OrderDelay(String orderId, long timeout) {
        this.orderId = orderId;
        this.timeout = timeout + System.nanoTime();
    }
    public int compareTo(Delayed other) { /* ... */ }
    public long getDelay(TimeUnit unit) {
        return unit.convert(timeout - System.nanoTime(), TimeUnit.NANOSECONDS);
    }
    void print() {
        System.out.println(orderId + "编号的订单要删除啦。。。。");
    }
}

Demo shows a 3‑second delay producing ordered output.

要去数据库扫描啦。。。

Pros: simple, easy to use, supports clustering. Cons: high memory consumption, latency up to the poll interval, heavy DB load, data loss on server restart.

(3) Netty HashedWheelTimer

Implements a time‑wheel similar to a clock. Each tick moves the pointer; tasks are placed in slots based on delay. Example code uses HashedWheelTimer with a TimerTask.

public class HashedWheelTimerTest {
    static class MyTimerTask implements TimerTask {
        boolean flag;
        MyTimerTask(boolean flag) { this.flag = flag; }
        public void run(Timeout timeout) throws Exception {
            System.out.println("要去数据库删除订单了。。。。");
            this.flag = false;
        }
    }
    public static void main(String[] args) {
        MyTimerTask timerTask = new MyTimerTask(true);
        Timer timer = new HashedWheelTimer();
        timer.newTimeout(timerTask, 5, TimeUnit.SECONDS);
        // wait loop …
    }
}

Pros: high efficiency, low latency. Cons: data lost on restart, complex cluster expansion, possible OOM under heavy load.

(4) Redis ZSET

Uses a sorted set where the score is the expiration timestamp and the member is the order ID. A consumer repeatedly checks the first element and processes it if the current time exceeds the score.

public void productionDelayMessage() {
    for (int i = 0; i < 5; i++) {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.SECOND, 3);
        int ts = (int) (cal.getTimeInMillis() / 1000);
        jedis.zadd("OrderId", ts, "OID000000" + i);
    }
}
public void consumerDelayMessage() {
    while (true) {
        Set<Tuple> items = jedis.zrangeWithScores("OrderId", 0, 0);
        if (items.isEmpty()) { Thread.sleep(500); continue; }
        int score = (int) ((Tuple) items.toArray()[0]).getScore();
        int now = (int) (System.currentTimeMillis() / 1000);
        if (now >= score) {
            String orderId = ((Tuple) items.toArray()[0]).getElement();
            Long removed = jedis.zrem("OrderId", orderId);
            if (removed != null && removed > 0) {
                System.out.println(System.currentTimeMillis() + "ms:redis消费了一个任务:" + orderId);
            }
        }
    }
}

Pros: high efficiency, low latency, easy cluster scaling. Cons: requires Redis maintenance, possible data loss on restart.

(5) Redis Keyspace Notifications

Enables callbacks when a key expires. By setting notify-keyspace-events Ex in redis.conf, a subscriber receives expiration events and can process order cancellation.

public class RedisTest {
    static void init() {
        new Thread(() -> jedis.subscribe(new RedisSub(), "__keyevent@0__:expired")).start();
    }
    public static void main(String[] args) throws InterruptedException {
        init();
        for (int i = 0; i < 10; i++) {
            String orderId = "OID000000" + i;
            jedis.setex(orderId, 3, orderId);
        }
    }
    static class RedisSub extends JedisPubSub {
        public void onMessage(String channel, String message) {
            System.out.println(System.currentTimeMillis() + "ms:" + message + "订单取消");
        }
    }
}

Pros: reliable notification, easy clustering, accurate timing. Cons: requires Redis configuration and extra maintenance.

(6) RabbitMQ Delayed Queue

RabbitMQ supports message TTL ( x-message-ttl) and dead‑letter exchange routing ( x-dead-letter-exchange) to implement delayed processing. By configuring a queue with TTL and a dead‑letter queue, messages are automatically transferred after the delay.

Implementation details are omitted for brevity.

Pros: high efficiency, built‑in clustering, message persistence adds reliability. Cons: adds operational complexity and cost due to RabbitMQ dependency.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaSchedulingRabbitMQdelayed tasksQuartz
Su San Talks Tech
Written by

Su San Talks Tech

Su San, former staff at several leading tech companies, is a top creator on Juejin and a premium creator on CSDN, and runs the free coding practice site www.susan.net.cn.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.