Browse Source

feat[litemall-core]: 支持延迟队列任务

Junling Bu 6 years ago
parent
commit
d8ccd13751

+ 45 - 0
litemall-core/src/main/java/org/linlinjava/litemall/core/task/Task.java

@@ -0,0 +1,45 @@
+package org.linlinjava.litemall.core.task;
+
+import java.util.concurrent.Delayed;
+import java.util.concurrent.TimeUnit;
+
+public abstract class Task implements Delayed, Runnable{
+    private String id = "";
+    private long start = 0;
+
+    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 (int)(this.getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS));
+    }
+
+    @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();
+    }
+}

+ 47 - 0
litemall-core/src/main/java/org/linlinjava/litemall/core/task/TaskService.java

@@ -0,0 +1,47 @@
+package org.linlinjava.litemall.core.task;
+
+import com.sun.org.apache.bcel.internal.generic.ARETURN;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import java.util.Iterator;
+import java.util.concurrent.DelayQueue;
+import java.util.concurrent.Executors;
+
+
+@Component
+public class TaskService {
+    private TaskService taskService;
+    private DelayQueue<Task> delayQueue =  new DelayQueue<Task>();
+
+    @PostConstruct
+    private void init() {
+        taskService = this;
+
+        Executors.newSingleThreadExecutor().execute(new Runnable() {
+            @Override
+            public void run() {
+                while (true) {
+                    try {
+                        Task task = delayQueue.take();
+                        task.run();
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+        });
+    }
+
+    public void addTask(Task task){
+        if(delayQueue.contains(task)){
+            return;
+        }
+        delayQueue.add(task);
+    }
+
+    public void removeTask(Task task){
+        delayQueue.remove(task);
+    }
+
+}

+ 24 - 0
litemall-core/src/main/java/org/linlinjava/litemall/core/util/BeanUtil.java

@@ -0,0 +1,24 @@
+package org.linlinjava.litemall.core.util;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+@Component
+public class BeanUtil implements ApplicationContextAware {
+    protected static ApplicationContext context;
+
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        context = applicationContext;
+    }
+
+    public static Object getBean(String name) {
+        return context.getBean(name);
+    }
+
+    public static <T> T getBean(Class<T> c){
+        return context.getBean(c);
+    }
+}

+ 71 - 0
litemall-core/src/test/java/org/linlinjava/litemall/core/TaskTest.java

@@ -0,0 +1,71 @@
+package org.linlinjava.litemall.core;
+
+import com.google.common.primitives.Ints;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.linlinjava.litemall.core.task.Task;
+import org.linlinjava.litemall.core.task.TaskService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.context.annotation.Primary;
+import org.springframework.core.env.Environment;
+import org.springframework.core.task.SyncTaskExecutor;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+import org.springframework.test.context.web.WebAppConfiguration;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Objects;
+import java.util.concurrent.Delayed;
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+
+@WebAppConfiguration
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringBootTest
+public class TaskTest {
+    private final Log logger = LogFactory.getLog(TaskTest.class);
+    @Autowired
+    private TaskService taskService;
+
+    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);
+        }
+
+    }
+
+    @Test
+    public void test() {
+        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        String now = df.format(LocalDateTime.now());
+        System.out.println("start at time=" + now);
+
+        taskService.addTask(new DemoTask("3", 1000));
+        taskService.addTask(new DemoTask("2", 2000));
+        taskService.addTask(new DemoTask("1", 3000));
+
+        taskService.addTask(new DemoTask("4", 1500));
+        taskService.addTask(new DemoTask("5", 2500));
+        taskService.addTask(new DemoTask("6", 3500));
+
+        try {
+            Thread.sleep(10 * 1000);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+}