我的main中有一个无限循环,它运行一个也是无限循环的作业,并等待它抛出错误。然后它会睡眠一段时间并再次开始任务。
public static void main(String[] args) {
while (true) {
try {
MyClass myClass = new MyClass();
myClass.startInfiniteLoop();
}
catch (SomeException ex) {
try {
Thread.sleep(MyClass.DEFAULT_SLEEP_TIME);
}
catch (InterruptedException ex2) {
System.exit(-1);
}
}
}
}
这很好用,但我想知道这是否可以做得更好,可能是ExecutorService
因为我(和我的IDE)不喜欢Thread.sleep()
循环中的while (true)
。
我已经阅读了很多关于ScheduledExecutorService
和任务管理的问题及其答案,但我没有找到这个特殊情况,因为它不是真正的时间表,我不知道是否以及何时进行任务结束。
答案 0 :(得分:3)
您可以使用ScheduledExecutorService
:
ScheduledExecutorService s=Executors.newScheduledThreadPool(1);
s.scheduleWithFixedDelay(new Runnable() {
public void run() {
try {
MyClass myClass = new MyClass();
myClass.startInfiniteLoop();
} catch(SomeException ex) {}
}
}, 0, MyClass.DEFAULT_SLEEP_TIME, TimeUnit.MILLISECONDS);
关键点是使用scheduleWithFixedDelay
而不是scheduleAtFixedRate
来确保之间的指定的时间与后续执行一样,就像使用sleep
方法一样。但请注意,即使使用“固定费率”,新执行也不会在旧执行尚未完成时启动。 It’s documentation说:“如果此任务的执行时间超过其周期,则后续执行可能会延迟,但不会同时执行。”
进一步请注意,您仍然需要像我的代码示例中那样捕获异常,否则执行程序将在抛出未捕获的异常后取消计划任务。
答案 1 :(得分:0)
如果您可以使用MyClass并将其重新编写为具有Runnable,该Runnable只执行MyClass的一次循环迭代,那么您可以使用调度执行程序服务,告诉服务每次运行Runnable一次
---根据快速示例的要求更新---
以下不是严格正确的Java代码,它是pesudo-java。
public class MyRepeatingTask implements Runnable {
private final ScheduledThreadpoolExecutor executor;
public MyRepeatingTask(ScheduledThreadpoolExecutor executor) {
this.executor = executor;
}
public void run() {
try {
doMyVariableLengthThing();
// alternatively, you could also schedule a new instance
executor.schedule(this, 1, TimeUnit.SECONDS);
} catch (Exception e) {
cleanup();
}
}
}
然后开始滚球
ScheduledThreadpoolExecutor executor = new ScheduledThreadpoolExecutor(1);
executor.execute(new MyRepeatingTask(executor));