【问题标题】:Java ScheduledExecutorService to run periodicallyJava ScheduledExecutorService 定期运行
【发布时间】:2017-03-02 06:45:29
【问题描述】:

我正在尝试每分钟运行一个作业 [其中包含 3 个应该并行运行的服务]。下面是我的代码 sn-p。

ExecutorService service = Executors.newFixedThreadPool(servicesMap.size());
for (Map.Entry entry : servicesMap.entrySet()) {
    service.submit(new MyService(conn, serviceID)); 
   // here serviceID is id1 id2 id3 these three job should execute parallel
}

注意:MyTask 实现 Callable & servicesMap 将始终为 3

如果我尝试使用 ScheduledExecutorService,那么我将无法实现它。 它说 scheduleService.schedule 不接受 Callable 类型参数

ScheduledExecutorService scheduleService = Executors.newScheduledThreadPool(servicesMap.size());
for (Map.Entry entry : servicesMap.entrySet()) {
    scheduleService.schedule((new MyService(conn, serviceID)), 0, 60, TimeUnit.SECONDS);
}

请帮助修改 ScheduledExecutorService 代码以实现此目的。

【问题讨论】:

    标签: java executorservice scheduledexecutorservice


    【解决方案1】:

    您的schedule(…) 调用包含的参数多于the method 的参数。

    不过,我不确定你到底在追求什么。如果您想在一分钟内运行您的服务,请使用以下调用:

    scheduleService.schedule(new MyService(conn, serviceID), 60, TimeUnit.SECONDS);
    

    如果您希望每分钟运行一次服务(立即开始),请使用以下两个调用之一:

    scheduleService.scheduleAtFixedRate(new MyService(conn, serviceID), 0, 60, TimeUnit.SECONDS);
    scheduleService.scheduleWithFixedDelay(new MyService(conn, serviceID), 0, 60, TimeUnit.SECONDS);
    

    关于您在 cmets 中的后续问题:

    如何制作,在一分钟内 Service1 Service2 Service3 应该并行运行,然后下一分钟做同样的事情。

    ScheduledExecutorService scheduleService = …;
    Collection<Callable<Void>> services = …;
    Runnable svcRunner = new Runnable() {
        @Override
        public void run() {
            Collection<Future<Void>> futures = new ArrayList<>(services.size());
            // start all services in parallel
            for (Callable<Void> service : services) {
                // any ExecutorService would do here, i.e., doesn't have to be a
                // ScheduledExecutorService
                futures.add(scheduleService.submit(service));
            }
            // wait for all services to complete
            for (Future<Void> future : futures) {
                try {
                    future.get();
                } catch (InterruptedException | ExecutionException e) {
                    // TODO do something meaningful
                }
            }
        }
    };
    // run the scheduler every minute (i.e., one minute after the last service
    // has finished), starting now
    scheduleService.scheduleWithFixedDelay(svcRunner, 0, 60, TimeUnit.SECONDS);
    

    为简单起见,我将服务存储在一个集合中。如果需要,您也可以每次都重新创建它们。

    【讨论】:

    • 注意到 Chriki。因此,这将每分钟运行 Service1 Service2 Service3 独立和并行。如何制作,在一分钟内 Service1 Service2 Service3 应该并行运行,然后下一分钟做同样的事情。
    • Chriki.. for 循环 - 它将循环 3 次。在循环内部,我编写了 scheduleService.schedule。对吗?
    • 我们正在触发通知服务批处理。此批处理将运行每一分钟。我们需要在每分钟内并行运行 3 个服务,这三个服务将触发一封电子邮件和短信给不同的客户集。这件事我正在努力实现。如果我的解释不明白,请告诉我。
    • 如果您不介意,请您告诉我,对于这种工作,我们是否需要使用连接池或如何管理连接,如果我们需要停止此服务如何关闭下来。
    • 给定的代码应该适用于您的场景。为了以后能够取消预定服务运行器,您应该在需要时跟踪returned ScheduledFuture&lt;?&gt;cancel()。至于连接池问题,您可能希望在 SO 上创建一个新问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-27
    • 1970-01-01
    • 2017-10-17
    相关资源
    最近更新 更多