我有一些任务需要在每个任务的定义间隔内反复执行,每个任务必须在各自不同的线程中执行。
示例:假设我有 task1,task2,task3,task4 ..... taskN
我想在定义的时间间隔内一次又一次地执行每项任务 例如
并且对于每个任务,应该创建不同的不同线程,而不是for循环类型,
请建议方法并分享示例java代码,或者说我有10个数据库查询,并且所有查询都必须在不同的线程中运行,并且在定义的间隔后一次又一次地直到无限...
答案 0 :(得分:3)
一个简单的解决方案是使用Java的ScheduledExecutorService
并使用scheduleAtFixedRate
方法。
ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
long initialDelay,
long delay,
TimeUnit unit)
Creates and executes a periodic action that becomes enabled first after the given initial
delay, and subsequently with the given delay between the termination of one execution
and the commencement of the next. If any execution of the task encounters an exception,
subsequent executions are suppressed. Otherwise, the task will only terminate
via cancellation or termination of the executor.
Parameters:
command - the task to execute
initialDelay - the time to delay first execution
delay - the delay between the termination of one execution
and the commencement of the next
unit - the time unit of the initialDelay and delay parameters
这是一个简单的例子,演示了延迟的工作原理:
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Example {
private static long START_TIME;
public static void main(String[] args) throws InterruptedException {
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(4);
START_TIME = System.currentTimeMillis();
Runnable task1 = printTask("T1");
Runnable task2 = printTask("T2");
Runnable task3 = printTask("T3");
Runnable task4 = printTask("T4");
scheduledExecutorService.scheduleAtFixedRate(task1, 3, 3, TimeUnit.SECONDS);
scheduledExecutorService.scheduleAtFixedRate(task2, 5, 3, TimeUnit.SECONDS);
scheduledExecutorService.scheduleAtFixedRate(task3, 0, 5, TimeUnit.SECONDS);
scheduledExecutorService.scheduleAtFixedRate(task4, 2, 2, TimeUnit.SECONDS);
Thread.sleep(15000);
scheduledExecutorService.shutdown();
scheduledExecutorService.awaitTermination(6000, TimeUnit.SECONDS);
}
private static Runnable printTask(String prefix) {
return () -> System.out.println(prefix + ": " + (System.currentTimeMillis() - START_TIME));
}
}
示例输出(1次运行)。您的结果应该相似,但可能不完全相同。每个任务首先在提供的initialDelay
中的unit
之后执行,然后安排在每个delay
之后执行:
T3: 38
T4: 2039
T1: 3039
T4: 4040
T2: 5040
T3: 5040
T1: 6039
T4: 6040
T2: 8040
T4: 8040
T1: 9039
T3: 10040
T4: 10040
T2: 11040
T1: 12039
T4: 12040
T2: 14039
T4: 14039
答案 1 :(得分:2)
对于我的建议,我建议Quartz。
您可以设置将在自己的线程上运行的tasks
。
示例,创建一个StatefulJob实现:
class RunQueryJob implements StatefulJob {
public void execute(JobExecutionContext jec) throws JobExecutionException {
try {
String query = (String) jec.getMergedJobDataMap().get("query");
//run query
} catch (Exception ex) {
//Handle Exception
}
}
}
初始化调度程序:
Scheduler scheduler;
scheduler = new StdSchedulerFactory().getScheduler();
scheduler.start();
创建一个安排方法:
public void scheduleQuery( String query, int seconds ){
JobDataMap map =new JobDataMap();
map.put("query", query);
JobDetail job = JobBuilder.newJob(RunQueryJob.class)
.usingJobData( map ).
build();
Trigger trigger = TriggerBuilder
.newTrigger()
.withSchedule(
CronScheduleBuilder.cronSchedule("0/"+seconds+" * * * * ?"))
.build();
scheduler.scheduleJob(job, trigger);
}
请注意CronScheduleBuilder.cronSchedule("0/"+seconds+" * * * * ?")
部分。您可以在scheduling syntax here上获得更多信息。
之后,你有一个方法可以这样使用:
scheduleQuery(&#34; QRY1&#34;,3); // RunQueryJob类将每隔3秒在一个新线程中运行&#34; QRY1&#34;在DataMap中。
答案 2 :(得分:1)
您可以使用java.util.concurrent提供的Executor服务。 This
可能会有所帮助。