【问题标题】:How to use ScheduledExecutorService to run the job periodically with multiple services如何使用 ScheduledExecutorService 通过多个服务定期运行作业
【发布时间】:2017-02-27 10:31:27
【问题描述】:

我正在尝试每分钟执行一个电子邮件作业。 Job 有 5 个服务。每 5 个服务应该并行运行。

使用 ExecutorService :

ExecutorService service = null;
if (serviceMap != null && serviceMap.size() > 0) {

    for (;;) {
        service = Executors.newFixedThreadPool(serviceMap.size());  // Here Service Map size will be 5
        for (Map.Entry entry : serviceMap.entrySet()) {
            service.submit(new EmailService(conn, mailParam));
        }
        service.shutdown();
        service.awaitTermination(1, TimeUnit.MINUTES);
    }
}

使用 ScheduledExecutorService :

ScheduledExecutorService scheduledExecutorService = null;
if (serviceMap != null && serviceMap.size() > 0) {
    scheduledExecutorService = Executors.newFixedThreadPool(serviceMap.size());  // Here Service Map size will be 5
    for (Map.Entry entry : serviceMap.entrySet()) {

        ScheduledFuture scheduledFuture =
                scheduledExecutorService.schedule(new EmailService(conn, mailParam),
                60,
                TimeUnit.SECONDS);
        System.out.println("result = " + scheduledFuture.get());
    }

    scheduledExecutorService.shutdown();
}

如果我使用 ExecutorService,每分钟我都会关闭该服务并再次执行该服务。没事吧?

如果我使用 ScheduledExecutorService,我无法编写代码来并行执行服务,也无法每分钟都运行该作业。

上面是我的代码 sn-p。请帮我解决它。

【问题讨论】:

标签: java executorservice scheduledexecutorservice


【解决方案1】:

首先,你应该调用newScheduledThreadPool()创建ScheduledExecutorService,这是正确的调度执行器服务。
然后你应该使用[scheduleAtFixedRate][1] 方法每分钟安排一个任务,初始延迟60秒。

ScheduledExecutorService scheduledExecutorService = null;
if (serviceMap != null && serviceMap.size() > 0) {
    scheduledExecutorService = Executors.newScheduledThreadPool(serviceMap.size());  // Here Service Map size will be 5
    for (Map.Entry entry : serviceMap.entrySet()) {
        scheduledExecutorService.scheduleAtFixedRate(new EmailService(conn, mailParam),
                60,
                60,
                TimeUnit.SECONDS);
    }
}

【讨论】:

  • scheduleAtFixedRate 要求 Runnable 作为参数,但我希望 Callable 作为参数。
  • 您可以改用RunnableFuture。但你最终得到 5 个ScheduledFuture。最好使用回调。
  • 好的 OLA 谢谢。既然是多线程的,每个线程需要不同的连接吗?
  • EmailService 会触发 5 组服务。在 EmailService 类中,我用 [Executors.newFixedThreadPool(5)] 编写了 ExecutorService
【解决方案2】:

好问题!!

你必须把它分成两个类。

一个是启动调度器。另一个用于执行实现 Callable 或 Runnable 接口的服务。

scheduledExecutorService.schedule() 与 service.submit() 不同。

schedule() 用于调度进程,而 submit 用于提交服务。

启动调度程序类:

public static void main(String[] args) {
        Class2 runnable = new Class2() {
          @Override
          public void run() {
            // call method that has ExecuteService Impl
          }
        };
        ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
        service.scheduleAtFixedRate(runnable, 0, 60, TimeUnit.SECONDS);
  }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-05
    相关资源
    最近更新 更多