我希望在Java中实现生成任务的机制。实际上,任务所做的与此处无关,可以通过线程或新进程来完成。
我真正需要的是:
有谁知道用Java可以做到这一点的框架吗?
最佳答案
我已经考虑了很长时间了,终于得到了一些您认为有用的东西。
我们的小“框架”的第一部分是Task
接口(interface):
public interface Task {
void work();
void stop();
}
实现这一点,我们可以设置我们的
WorkTask
:public class WorkTask implements Task {
@Override
public void work() {
// Do something useful...
// might throw SomethingNastyHappenedException
}
@Override
public void stop() {
// implement as needed e.g. to break inner loops
}
}
为了符合您能够重试的要求,我们创建了
Wrapper
类:public class RetryingTaskWrapper implements Task {
private Task wrappedTask;
private int maxTries;
private boolean running = false;
public RetryingTaskWrapper(Task wrappedTask, int maxTries) {
this.wrappedTask = wrappedTask;
this.maxTries = maxTries;
}
@Override
public void work() {
running = true;
boolean success = false;
int tries = 0;
while (running && !success && tries < maxTries) {
try {
wrappedTask.work();
success = true;
} catch (SomethingNastyHappenedException e) {
// something nasty happed so retry
tries++;
} catch (Exception e) {
// something even worse happened -> end
running = false;
}
}
running = false;
}
@Override
public void stop() {
running = false;
wrappedTask.stop();
}
}
最后,我们需要一些东西来执行任务...
public class TaskRunner implements Runnable {
private Thread thread;
private Task task;
private boolean running = false;
public TaskRunner(Task task) {
this.task = task;
}
public synchronized void start() {
if (thread != null) {
return;
}
thread = new Thread(this);
thread.start();
}
@Override
public void run() {
running = true;
if (task != null) {
try {
task.work();
} catch (Exception e) {
// log your exception
}
}
thread = null;
running = false;
}
public void stop() {
if (running) {
if (task != null) {
task.stop();
}
if (thread != null) {
thread.interrupt();
}
}
}
}
现在,我们需要做的就是设置一个TaskRunner并启动它:
WorkTask workTask = new WorkTask();
TaskRunner runner = new TaskRunner(new RetryingTaskWrapper(workTask, 5));
runner.start();
如果您只想运行一次
WorkTask
而不重试,那也是可行的:WorkTask workTask = new WorkTask();
TaskRunner runner = new TaskRunner(workTask);
runner.start();
如果您愿意,甚至可以无限循环运行
WorkTask
,而不必更改WorkTask
本身。您所需要做的就是创建另一个包装器public class InfiniteLoopTaskWrapper implements Task {
private Task wrappedTask;
private boolean running = false;
public InfiniteLoopTaskWrapper(Task wrappedTask) {
this.wrappedTask = wrappedTask;
}
@Override
public void work() {
running = true;
while (running) {
try {
wrappedTask.work();
} catch (SomethingNastyHappenedException e) {
// log that something nasty happened
} catch (Exception e) {
// something even worse happened -> end
running = false;
}
}
}
@Override
public void stop() {
running = false;
wrappedTask.stop();
}
}
并运行它...
WorkTask workTask = new WorkTask();
TaskRunner runner = new TaskRunner(new InfiniteLoopTaskWrapper(workTask));
runner.start();