java 中的多线程任务调度程序

multi threaded task scheduler in java

我有一些任务需要在每个任务的定义间隔内一次又一次地执行,并且每个任务都必须在自己不同的不同线程中执行。

示例:假设我有 task1,task2,task3,task4.....taskN

我想在定义的时间间隔内一次又一次地执行每个任务
例如

并且应该为每个任务创建不同的线程,而不是在 for 循环中,

请提出方法并分享示例 java 代码,或者说我有 10 个数据库查询,所有查询都必须在不同的线程中运行,并且在定义的时间间隔后一次又一次地运行直到无限..

关于日程安排,我推荐 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("QRY1", 3); //RunQueryJob class 将每 3 秒在一个新线程中 运行 通过 DataMap 中的 "QRY1"。

您可以使用 java.util.concurrent 提供的执行器服务。 This

可能会有帮助。

一个简单的解决方案是利用 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 运行)。您的结果应该相似,但可能不完全相同。每个任务首先在提供的 unit 中的 initialDelay 之后执行,然后安排在每个 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