
在Java中,当我们需要安排一些任务在未来的某个时间点执行时,
DelayQueue
Delayed
Java的
DelayQueue
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.BlockingQueue;
import java.util.Random;
// 1. 定义一个延迟任务类,实现Delayed接口
class DelayedTask implements Delayed {
    private String name;
    private long startTime; // 任务的执行时间点(纳秒)
    public DelayedTask(String name, long delayInMilliseconds) {
        this.name = name;
        // 计算任务的执行时间点,基于系统纳秒时间,这比毫秒时间更精确,也更适合计算相对延迟
        this.startTime = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(delayInMilliseconds);
    }
    @Override
    public long getDelay(TimeUnit unit) {
        // 计算剩余延迟时间
        long diff = startTime - System.nanoTime();
        return unit.convert(diff, TimeUnit.NANOSECONDS);
    }
    @Override
    public int compareTo(Delayed o) {
        // 按照任务的执行时间点进行排序,越早执行的排在前面
        long diff = this.getDelay(TimeUnit.NANOSECONDS) - o.getDelay(TimeUnit.NANOSECONDS);
        if (diff < 0) {
            return -1;
        } else if (diff > 0) {
            return 1;
        } else {
            return 0;
        }
    }
    @Override
    public String toString() {
        return "任务: " + name + ", 预计执行时间 (ns): " + startTime;
    }
    public void execute() {
        System.out.println(Thread.currentThread().getName() + " 正在执行任务: " + name + " (实际执行时间: " + System.currentTimeMillis() + "ms)");
    }
}
public class DelayQueueDemo {
    public static void main(String[] args) throws InterruptedException {
        BlockingQueue<DelayedTask> delayQueue = new DelayQueue<>();
        Random random = new Random();
        // 生产者:模拟添加延迟任务
        System.out.println("开始添加延迟任务...");
        for (int i = 0; i < 5; i++) {
            long delay = 1000 + random.nextInt(4000); // 1到5秒的随机延迟
            DelayedTask task = new DelayedTask("任务-" + (i + 1), delay);
            delayQueue.put(task);
            System.out.println("添加了 " + task.toString() + ", 延迟 " + delay + "ms (当前时间: " + System.currentTimeMillis() + "ms)");
        }
        // 消费者:从队列中取出并执行任务
        System.out.println("\n消费者线程开始等待任务...");
        while (!delayQueue.isEmpty()) {
            try {
                // take()方法会阻塞,直到有任务的延迟时间到期
                DelayedTask task = delayQueue.take();
                task.execute();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                System.err.println("消费者线程被中断。");
                break;
            }
        }
        System.out.println("所有延迟任务执行完毕。");
    }
}在Java生态中,处理延迟任务并非只有
DelayQueue
ScheduledThreadPoolExecutor
Timer
Timer
立即学习“Java免费学习笔记(深入)”;
ScheduledThreadPoolExecutor
ThreadPoolExecutor
而
DelayQueue
DelayQueue
PriorityQueue
Delayed
Delayed
compareTo
getDelay
System.nanoTime()
System.currentTimeMillis()
DelayQueue
Delayed
Delayed
DelayQueue
take()
DelayQueue
所以,何时选择
DelayQueue
DelayQueue
正确实现
Delayed
DelayQueue
DelayQueue
Delayed
getDelay(TimeUnit unit)
compareTo(Delayed o)
getDelay(TimeUnit unit)
这个方法应该返回当前任务距离其到期时间还剩多少延迟。如果任务已经到期,则应该返回0或负值。
TimeUnit unit
常见错误及正确实践:
System.currentTimeMillis()
System.currentTimeMillis()
System.nanoTime()
System.nanoTime()
DelayedTask
System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(delayInMilliseconds)
startTime
getDelay
startTime - System.nanoTime()
getDelay
unit
unit.convert(diff, TimeUnit.NANOSECONDS)
compareTo(Delayed o)
这个方法用于比较两个
Delayed
DelayQueue
PriorityQueue
PriorityQueue
常见错误及正确实践:
compareTo
getDelay
DelayQueue
compareTo
getDelay
DelayQueue
getDelay
compareTo
compareTo
getDelay
@Override
public int compareTo(Delayed o) {
    // 比较剩余延迟时间,剩余时间越短(即越早到期)的优先级越高
    long diff = this.getDelay(TimeUnit.NANOSECONDS) - o.getDelay(TimeUnit.NANOSECONDS);
    if (diff < 0) {
        return -1;
    } else if (diff > 0) {
        return 1;
    } else {
        return 0;
    }
}这种方式确保了队列总是将最快到期的任务放在队头。
getDelay
getDelay
compareTo
diff
总结来说,实现
Delayed
getDelay
compareTo
compareTo
System.nanoTime()
compareTo
getDelay
尽管
DelayQueue
内存消耗问题
DelayQueue
Delayed
DelayedTask
优化策略:
DelayedTask
DelayedTask
持久化与可靠性问题
DelayQueue
优化策略:
DelayQueue
DelayQueue
DelayQueue
消费者吞吐量与并发瓶颈
DelayQueue
take()
优化策略:
DelayQueue
DelayQueue
take()
ThreadPoolExecutor
// 示例:多线程消费者
// ... (DelayQueue和DelayedTask定义不变)
// ExecutorService用于执行任务
ExecutorService taskExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
// 消费者线程
new Thread(() -> {
    while (true) { // 生产环境中可能需要更优雅的退出机制
        try {
            DelayedTask task = delayQueue.take();
            taskExecutor.submit(() -> {
                task.execute(); // 在线程池中执行任务
            });
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            System.err.println("消费者线程被中断。");
            break;
        }
    }
}, "DelayQueue-Consumer").start();
// ... (主线程添加任务)
// 应用程序关闭时,需要关闭taskExecutor
// taskExecutor.shutdown();监控与调试
DelayQueue
优化策略:
DelayQueue
总而言之,
DelayQueue
以上就是Java中使用DelayQueue实现延迟任务的详细内容,更多请关注php中文网其它相关文章!
 
                        
                        每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
 
                Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号