DelayQueue达到定时触发效果

2022年1月15日 3点热度 0条评论 来源: 老王的笔记

DelayQueue的特点就是插入Queue中的数据可以按照自定义的delay时间进行排序。只有delay时间小于0的元素才能够被取出。

这样子,只要开启一个线程循环从DelayQueue中取值执行,就可以达到想要的效果

定义

  1. 执行的任务类

    public abstract class Task implements Delayed, Runnable{
        private String id = "";
        private long start = 0;
    
        /**
         * @param id id
         * @param delayInMilliseconds 延时时间(单位:毫秒)
         */
        public Task(String id, long delayInMilliseconds){
            this.id = id;
            this.start = System.currentTimeMillis() + delayInMilliseconds;
        }
    
        public String getId() {
            return id;
        }
    
        @Override
        public long getDelay(TimeUnit unit) {
            long diff = this.start - System.currentTimeMillis();
            return unit.convert(diff, TimeUnit.MILLISECONDS);
        }
    
        @Override
        public int compareTo(Delayed o) {
            return Ints.saturatedCast(this.start - ((Task) o).start);
        }
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null) return false;
            if (!(o instanceof Task)) {
                return false;
            }
            Task t = (Task)o;
            return this.id.equals(t.getId());
        }
    
        @Override
        public int hashCode() {
            return this.id.hashCode();
        }
    }
    
  2. 任务处理类

    @Component
    public class TaskService {
        private TaskService taskService;
    		// Task是自定义任务类,public abstract class Task implements Delayed, Runnable
        private DelayQueue<Task> delayQueue =  new DelayQueue<Task>();
        // 被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器执行一次
        @PostConstruct
        private void init() {
            taskService = this;
            // 开线程死循环执行任务
            new Thread(() -> {
                while (true) {
                    try {
                        Runnable task = delayQueue.take();
                        task.run();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
        // 添加任务
        public void addTask(Task task){
            if(delayQueue.contains(task)){
                return;
            }
            delayQueue.add(task);
        }
    
        public void removeTask(Task task){
            delayQueue.remove(task);
        }
    
    }
    

使用

  1. 新建自定义的任务类,需要继承Task

    private class DemoTask extends Task {
    
        DemoTask(String id, long delayInMilliseconds){
            super(id, delayInMilliseconds);
        }
        @Override
        public void run() {
            DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            String now = df.format(LocalDateTime.now());
            System.out.println("task id=" + this.getId() + " at time=" + now);
        }
    
    }
    
  2. 使用

    taskService.addTask(new DemoTask("1", 3000));
    

代码来源:

https://github.com/linlinjava/litemall

    原文作者:老王的笔记
    原文地址: https://www.cnblogs.com/konghuanxi/p/16259149.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系管理员进行删除。