我的任务包含20个不同的步骤:
public class MyTask implements Runnable {
@Override
public void run() {
// Step #1. Fetch data
Data data = fetchData();
// Step #2. Do something with data
SomeResult result = dataProcessor.process(data);
// ...
// Step #19. Generate report
Report report = reportFactory.newReport(result);
// Step #20. Clean up
cleanUp();
}
}
我想:
STARTING_POINT
。Timer
开始每分钟一次又一次地运行任务(ScheduledExecutorService
?STARTING_POINT
?)。run()
)。STARTING_POINT
重置为当前时间(System.currentTimeInMillis()
?)并再次开始每分钟循环,但是从新{{1 }}。STARTING_POINT
或类似的东西调用的外部“控制”线程中断。例如,假设该应用启动,ShutdownHook
是2/4/2014 11:15:36 EST。假设第1个循环完全 1分钟,以完成执行STARTING_POINT
内的所有20个步骤。然后它将在11:15:36到11:16:36之间执行,然后第二个周期将重新开始并调用run()
。让我们说这个周期很慢,当我们到达11:17:36时,它只在第11步。它将关闭并停止执行,然后第三个周期将重新开始并调用run()
。如果这个周期很快并且在11:17:53之前完成run()
,那么run()
将成为2/4/2014 11:17:53,并且第4个周期将开始执行并调用再次STARTING_POINT
。等
我完全不知道从哪里开始挖掘这个。有任何想法吗?我愿意使用JDK附带的任何东西,以及除Apache Camel之外的任何开源库。
答案 0 :(得分:1)
看起来Spring Batch会是一个很好的选择。我会推荐它。
您可以使用spring integrated quartz scheduler安排作业。 作业将分为多个步骤(也可以实现并行性)。 乔布斯可以重新开始,最重要的是,你只需要很少的工作。
大多数东西都正确接线。我提供了一个bean配置作为示例。
<bean id="threadPoolExecutor"
class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="20" />
<property name="maxPoolSize" value="25" />
<property name="queueCapacity" value="500" />
</bean>
<bean id="jobLauncher"
class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
<property name="taskExecutor" ref="asyncTaskExecutor" />
</bean>
<batch:job id="batchjob" job-repository="jobRepository">
<batch:step id="step1" next="step2">
<batch:tasklet ref="start" />
</batch:step>
<batch:step id="step2" next="step3.master">
<batch:tasklet ref="fetchData" />
</batch:step>
<batch:step id="step3.master">
<batch:partition step="step3.slave"
partitioner="processingPartitioner">
<batch:handler grid-size="20" task-executor="threadPoolExecutor" />
</batch:partition>
</batch:step>
<batch:listeners>
<batch:listener ref="MyListener" />
</batch:listeners>
</batch:job>
<batch:step id="step3.slave">
<batch:tasklet ref="processFile" />
</batch:step>
<bean id="myLauncher" class="com.<>.batch.MyLauncher">
<property name="job" ref="batchJob" />
<property name="jobLauncher" ref="jobLauncher" />
</bean>
<task:scheduled-tasks>
<task:scheduled ref="myLauncher" method="launch"
cron="0 0 0 0 0 1" />
</task:scheduled-tasks>
可以定义每个步骤,并且应该实现Tasklet。弹簧本身提供了一些例子。
答案 1 :(得分:0)
cancel()将取消当前线程。你可以在20种方法中检查每种方法后的时间并致电取消。
time2.scheduleAtFixedRate(new TimerTask() {
long t0 = System.currentTimeMillis();
@Override
public void run() {
if (System.currentTimeMillis() - t0 ) {
cancel();
} else {
sendSamples();
}
}