在特定时间运行Java线程

7
我有一个Web应用程序,每小时与中央数据库同步四次。 这个过程通常需要2分钟。 我想在X:55、X:10、X:25和X:40运行此进程作为线程,以便用户知道在X:00、X:15、X:30和X:45他们有一个干净的数据库副本。 这只是管理期望。 我已经使用了java.util.concurrent中的执行器,但调度是使用scheduleAtFixedRate完成的,我认为它不能保证在哪些小时实际运行。 我可以使用第一个延迟来启动Runnable,使第一个接近启动时间,并安排每15分钟运行一次,但似乎这可能会随着时间的推移而发散。 有没有更简单的方法来安排线程在每个刻钟之前5分钟运行?
3个回答

9
你可以让Runnable安排它的“下一次运行”。
例如,
class Task implements Runnable {
    private final ScheduledExecutorService service;

    public Task(ScheduledExecutorService service){
        this.service = service;
    }

    public void run(){
        try{
             //do stuff
        }finally{
            //Prevent this task from stalling due to RuntimeExceptions.
            long untilNextInvocation = //calculate how many ms to next launch
            service.schedule(new Task(service),untilNextInvocation,TimeUnit.MILLISECONDS);
        }
    }
}

1
@rmarimon:没问题 :) 只要小心 RuntimeException 可能会停止周期性执行。我曾经因此而受到伤害,所以我相应地编辑了答案。 - Enno Shioji
我刚刚进行了更改。我之前是用的try { } catch (Exception e) { },然后再重新安排任务。但是finally似乎是正确的方法。 - Ricardo Marimon

2
"

Quartz会是一个很好的选择,因为你的应用程序是基于Web的。它将提供你所需的细粒度时间调度。

Quartz是一个功能齐全的开源作业调度服务,可以与任何Java EE或Java SE应用程序集成或并行使用,从最小的独立应用程序到最大的电子商务系统。Quartz可用于创建简单或复杂的计划,以执行数十个、数百个甚至数万个任务;这些任务的任务被定义为标准的Java组件,可以执行几乎任何你编程要求它们执行的任务。Quartz调度程序包括许多企业级功能,如JTA事务和集群。

"

1

TimerTask 处理这种情况。

请参见 schedule(TimerTask, Date)

如果您不想一直进行作业调度,可以考虑使用类似于 Quartz 的作业调度工具。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接