任务的分钟长轮询或单个调度程序 - 通知系统的方法
Long polling in minute or single scheduler for a task - Approach for a notification system
我有一个需求,我会在一定的时间间隔内计划多个任务。对于每个任务,必须在特定时间间隔推送通知。
我有两种方法,要么编写一个调度程序,每隔一分钟轮询一次并相应地推送通知。或者我可以安排为每个任务初始化一个调度程序。使用前一种方法,解决方案非常简单,使用后一种方法,我可以更好地控制调度程序,例如,我可以为每个任务专门设置初始延迟(这是一项要求),然后停止单个任务,恢复等。到目前为止,我正在使用后一种方法。 但我想知道在单个应用程序中使用这么多调度程序是否会更好。还是使用 1 分钟轮询的单个调度程序更好?。平均而言,我一次会处理大约 200 多个任务。或者为此我可以依赖 任何其他库?
到目前为止我的代码
Sheduler 这是一个 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
,它将满足您的所有需求。
当您需要安排任务并将其传递给调度程序时创建上下文。
我有一个需求,我会在一定的时间间隔内计划多个任务。对于每个任务,必须在特定时间间隔推送通知。 我有两种方法,要么编写一个调度程序,每隔一分钟轮询一次并相应地推送通知。或者我可以安排为每个任务初始化一个调度程序。使用前一种方法,解决方案非常简单,使用后一种方法,我可以更好地控制调度程序,例如,我可以为每个任务专门设置初始延迟(这是一项要求),然后停止单个任务,恢复等。到目前为止,我正在使用后一种方法。 但我想知道在单个应用程序中使用这么多调度程序是否会更好。还是使用 1 分钟轮询的单个调度程序更好?。平均而言,我一次会处理大约 200 多个任务。或者为此我可以依赖 任何其他库?
到目前为止我的代码 Sheduler 这是一个 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
,它将满足您的所有需求。
当您需要安排任务并将其传递给调度程序时创建上下文。