java - 任务的分钟长轮询或单个调度程序 - 通知系统的方法

标签 java optimization scheduledexecutorservice

我有一个要求,我将在一定的时间间隔内计划多个任务。对于每个任务,都必须以一定的时间间隔推送通知。 我有两种方法,要么编写一个调度程序,该调度程序将每隔一分钟轮询并相应地推送通知。或者我可以安排为每个任务初始化一个调度程序。使用前一种方法,解决方案非常简单,使用后一种方法,我可以对调度程序进行更多控制,例如,我可以专门为每个任务设置初始延迟(这是一个要求),然后停止单个任务,恢复等。到目前为止,我正在继续使用后一种方法。 但我想知道在单个应用程序中使用这么多调度程序是否会更好。或者使用具有 1 分钟轮询的单个调度程序更好?。平均而言,我一次会处理大约 200 多个任务。或者为此我可以依赖任何其他库吗?

到目前为止我的代码 Scheduler 这是一个 ExecutorService

       //Constructor
            public TaskScheduler(String taskName) {
                this.taskName = taskName;
                this.taskResult = new TaskResult();
                this.taskResult.setStartTime(getNewDate());
                scheduledExecutorService = Executors.newScheduledThreadPool(1);
//DB Operation
            }


    // To stop an individual task
                public TaskResult stop() throws InterruptedException {
                    try {
                        System.out.println("Stopping : " + this.taskName);
                        this.taskResult.setTaskName(this.taskName);
                        this.taskResult.setEndTime(new Date());
                        scheduledFuture.cancel(false);
                        scheduledExecutorService.shutdown();
//DB Operation 
                        System.out.println("Stopping : finished - " + this.taskName + " @ "+ new Date());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return this.taskResult;
                }

        //Portion to add task
            public TaskScheduler schedule(Runnable task, long initialDelay, long frequency) throws Exception{
                this.taskResult.setFrequencyInSeconds(frequency);
                scheduledFuture = scheduledExecutorService.scheduleAtFixedRate(task, initialDelay, frequency, TimeUnit.SECONDS);
                return this;
            }

任务具有业务逻辑的线程

        public class TaskModel implements Runnable {
            private String taskName;

            public TaskModel() {

            }

            public TaskModel(String taskName) {
                this.taskName = taskName;
            }

            @Override
            public void run() {
//     DB operations
    .
    .

最佳答案

最好使用单个调度程序,但您不需要为此编写自己的调度程序。您可以使用具有一定数量线程的单实例 Executors.newScheduledThreadPool(1) 来安排所有任务。

考虑以下代码:

class TaskScheduler {
    private ScheduledExecutorService scheduledExecutorService;

    public TaskScheduler(int threads) {
        this.scheduledExecutorService = Executors.newScheduledThreadPool(threads);
    }

    //Portion to add task
    public TaskExecutionContext schedule(String taskName, Runnable task, long initialDelay, long frequency) {
        TaskExecutionContext context = new TaskExecutionContext(taskName);
        context.getTaskResult().setFrequencyInSeconds(frequency);
        ScheduledFuture scheduledFuture = scheduledExecutorService.scheduleAtFixedRate(task, initialDelay, frequency, TimeUnit.SECONDS);
        context.setScheduledFuture(scheduledFuture);
        return context;
    }
}

class TaskExecutionContext {
    private String taskName;
    private TaskResult taskResult;

    private ScheduledFuture scheduledFuture;

    public TaskExecutionContext(String taskName) {
        this.taskName = taskName;
        this.taskResult = new TaskResult();
        this.taskResult.setTaskName(taskName);
        this.taskResult.setStartTime(new Date());
        //DB Operation on creation
    }

    public TaskResult stop() {
        try {
            System.out.println("Stopping : " + this.taskName);
            this.taskResult.setTaskName(this.taskName);
            this.taskResult.setEndTime(new Date());
            scheduledFuture.cancel(false);
//DB Operation on stopping
            System.out.println("Stopping : finished - " + this.taskName + " @ " + new Date());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return this.taskResult;
    }

    public TaskResult getTaskResult() {
        return this.taskResult;
    }

    public void setScheduledFuture(ScheduledFuture scheduledFuture) {
        this.scheduledFuture = scheduledFuture;
    }
}

如果您需要一些关于计划、创建和停止任务的额外操作 - 也许最好有单独的 TaskExecutionContext,它将执行您的所有需求。

当您需要安排任务并将其传递给调度程序时创建上下文。

关于java - 任务的分钟长轮询或单个调度程序 - 通知系统的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56373435/

相关文章:

java - 当子字符串多于值时,将重复出现的子字符串替换为数组值

java - VLCJ:播放 1 秒后 Java 运行时环境检测到 fatal error

java - 将 JSON 字符串分隔为 android 中的变量

linq-to-sql - 如何优化统计计数顺序以及为何如此缓慢

Java Scheduled Executor 服务功能

java - 如何知道 Runnable 被安排重复执行

java - 表名未使用 jpa 映射

javascript - 一个模块 : OPTIMIZER FAILED: InternalError: missing name after . 运算符(operator)的 Dojo 构建失败

numpy - 为什么 numpy.absolute() 这么慢?

java - ExecutorService 在 JUnit 测试中不执行 Runnables