DelayQueue达到定时触发效果

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. 任务处理类

    @Componentpublic 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

0 个评论

要回复文章请先登录注册