【问题标题】:Concurrent execution of scheduled tasks in JavaJava中计划任务的并发执行
【发布时间】:2013-07-23 06:05:51
【问题描述】:

我有一个 TimerTask,旨在以特定时间间隔收集指标。但是,任务执行的周期可能小于任务执行的时间(有时如果某些事情超时并被延迟)。

有没有办法在不等待前一个任务完成的情况下同时执行多个 TimerTasks 或 Runnables、线程等?

我知道Timer使用单线程,ScheduledThreadPoolExecutor不管速率如何都会延迟执行。

谢谢。

【问题讨论】:

  • 那么您能否更具体地解释一下为什么ScheduledThreadPoolExecutor.scheduleAtFixedRate(..) 不适合您的需求?
  • 根据 API 和我使用它的测试... "如果此任务的任何执行时间超过其周期,则后续执行可能会延迟开始,但不会同时执行。 " 来自Java API

标签: java multithreading concurrency timer scheduling


【解决方案1】:

我建议您将 Executors.newCachedThreadPool()newCachedThreadPool(ThreadFactory threadFactory) 与您自己的线程工厂一起使用,并与 Timer 结合使用。所以代码应该是这样的

Executor executor = Executors.newCachedThreadPool();
Timer time = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {

    public void run() {
        executor.execute(new Runnable() {

             public void run() {
                  //your business logic
             }
        });
    }
}, delay, period);

这样你可以安排一些时间段的任务,它们都会同时运行。

【讨论】:

  • 明白了...谢谢!如果有人可以解释它是如何工作的,而不是 Timer 方法或 Scheduler 方法,我将不胜感激。基本上这是如何绕过阻塞的。
  • 原因是定时器有它自己的线程,这个线程唯一做的就是将任务分派给CachedThreadPool,然后它几乎在一个单独的线程中运行每个新任务。我希望我解释清楚:) 如果你不明白的话,你可以问更多
  • 好吧显然这不起作用...我不知道发生了什么...我使用了上面的代码,似乎如果线程 B 在线程 A 之前完成,则计时器“赶上" 并快速连续触发其他线程。我查看了可运行文件上的时间戳,发现有超过 14 个对象都具有相同的时间戳。在这一点上,我不知所措。
  • 您是否尝试过在Executors.newCachedThreadPool(ThreadFactory threadFactory) 中使用自定义线程工厂?这个工厂真的可以这么简单class SimpleThreadFactory implements ThreadFactory { public Thread newThread(Runnable r) { return new Thread(r); }}
【解决方案2】:

使用任何 Timer 实现,包括 ScheduledThreadPoolExecutor,但让您的计时器任务不执行您的业务逻辑,而是快速启动另一个实际执行繁重计算的任务(到缓存的线程池,或在其自己新创建的线程上)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-07
    • 1970-01-01
    • 2016-08-14
    • 1970-01-01
    • 2011-12-08
    相关资源
    最近更新 更多