我们总会遇到需要使用批次任务处理问题的场景,任务有很多不同类型的任务,同时这些任务可能都有大致相同,甚至抽象出来共同的执行阶段状态。
任务的执行肯定无法保证一帆风顺,总会在某个时间阶段被打断,这个时候我们需要设计一个可以断点重续的任务,下面则通过模板模式实现一个这样的通用流程:
可以通过实现它自定义自己的任务类,对应不同的任务,比如扫地任务、洗碗任务
public interface Task {
String getType();
TaskStatus getStatus();
void setStatus(TaskStatus status);
void startExcute();
void runExcute();
void pauseExcute();
void endExcute();
}
public enum TaskStatus {
START,RUNNING, PAUSED, COMPLETED,FAILED
}
public class ConcreteTask1 implements Task {
private String type;
private TaskStatus status;
public ConcreteTask1(String type, TaskStatus taskStatus) {
this.type = type;
this.status = taskStatus;
}
@Override
public String getType() {
return type;
}
@Override
public TaskStatus getStatus() {
return status;
}
@Override
public void setStatus(TaskStatus status) {
this.status = status;
}
public void startExcute() {
System.out.println("任务类型:" + type + ",阶段-开始");
// 更新任务状态
setStatus(TaskStatus.START);
runExcute();
}
public void runExcute() {
System.out.println("任务类型:" + type + ",阶段-执行中");
// 更新任务状态
setStatus(TaskStatus.RUNNING);
pauseExcute();
}
public void pauseExcute() {
System.out.println("任务类型:" + type + ",阶段-重启则可继续...");
// 更新任务状态
setStatus(TaskStatus.PAUSED);
endExcute();
}
public void endExcute() {
System.out.println("任务类型:" + type + ",阶段-结束");
// 更新任务状态
setStatus(TaskStatus.COMPLETED);
}
}
可以在这里定义任务执行入口,传入你的任务类。
入口方法中可以增加各个阶段状态的判断逻辑,以便梳理执行顺序,是断点重续的关键
public interface TaskProcessor {
void process(Task task);
}
通用模板定义一些必须的方法,或者流程
public class ConcreteTaskManager extends TaskManagerTemplate {
public ConcreteTaskManager(int maxThreads) {
super(maxThreads);
}
@Override
protected void handleTaskError(Task task, Exception e) {
// 具体处理任务错误的逻辑
System.out.println("Error handling for task: " + task.getType());
}
}
public abstract class TaskManagerTemplate {
private ExecutorService executorService;
public TaskManagerTemplate(int maxThreads) {
executorService = Executors.newFixedThreadPool(maxThreads);
}
public void executeTasks(List<Task> tasks, TaskProcessor taskProcessor) {
for (Task task : tasks) {
executorService.execute(() -> {
// 执行通用任务处理流程
try {
taskProcessor.process(task);
task.setStatus(TaskStatus.COMPLETED);
} catch (Exception e) {
// 处理任务执行异常
task.setStatus(TaskStatus.PAUSED);
handleTaskError(task, e);
}
});
}
shutdown();
}
public void shutdown() {
executorService.shutdown();
}
// 留给子类实现的处理任务错误的方法
protected abstract void handleTaskError(Task task, Exception e);
}
认真看看
public class TemplateTask {
public static void main(String[] args) {
// 创建具体任务管理器,指定最大线程数
ConcreteTaskManager taskManager = new ConcreteTaskManager(4);
// 从数据库加载任务数据
List<Task> tasks = loadTasksFromDatabase();
// 创建任务处理器
TaskProcessor taskProcessor = new TaskProcessor() {
@Override
public void process(Task task) {
// 任务执行逻辑
if (task.getStatus() == TaskStatus.START) {
task.startExcute();
task.setStatus(TaskStatus.START);
} else if (task.getStatus() == TaskStatus.RUNNING) {
task.runExcute();
task.setStatus(TaskStatus.RUNNING);
} else if (task.getStatus() == TaskStatus.PAUSED) {
task.pauseExcute();
task.setStatus(TaskStatus.PAUSED);
} else if (task.getStatus() == TaskStatus.COMPLETED) {
task.endExcute();
task.setStatus(TaskStatus.COMPLETED);
} else {
System.out.println("执行失败");
task.setStatus(TaskStatus.FAILED);
}
}
};
// 提交任务到任务管理器
taskManager.executeTasks(tasks, taskProcessor);
}
private static List<Task> loadTasksFromDatabase() {
// 从数据库中加载任务数据,包括类型和状态
// 返回任务列表
// 这里简化为手动创建任务列表
List<Task> tasks = new ArrayList<>();
tasks.add(new ConcreteTask1("Type1", TaskStatus.START));
tasks.add(new ConcreteTask1("Type2", TaskStatus.RUNNING));
tasks.add(new ConcreteTask1("Type3", TaskStatus.PAUSED));
tasks.add(new ConcreteTask1("Type4", TaskStatus.COMPLETED));
// 添加其他任务
return tasks;
}
}