DelayQueue达到定时触发效果
DelayQueue的特点就是插入Queue中的数据可以按照自定义的delay时间进行排序。只有delay时间小于0的元素才能够被取出。
这样子,只要开启一个线程循环从DelayQueue中取值执行,就可以达到想要的效果
定义
-
执行的任务类
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(); } }
-
任务处理类
@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); } }
使用
-
新建自定义的任务类,需要继承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); } }
-
使用
taskService.addTask(new DemoTask("1", 3000));
代码来源:
https://github.com/linlinjava/litemall