【问题标题】:Concurrently running Schedules Jobs using Play! Framework使用 Play 并发运行计划作业!框架
【发布时间】:2011-06-09 23:37:11
【问题描述】:

我有戏!每 30 秒执行一次的框架作业:

@Every("30s")
public class MyJob extends Job { ... }

这项工作会做一些事情,例如阅读电子邮件和写入数据库。但是,作业可能无法在 30 秒内完成。如果作业花费的时间超过 30 秒,我想 kill 在原始作业仍在进行时尝试启动的后续作业。有没有办法做到这一点?甚至暂停后续工作,直到原始工作完成?

【问题讨论】:

    标签: java playframework


    【解决方案1】:

    据我所知,您不必终止工作。我创建了一个作业,而不是每分钟运行一次,但在某些情况下,它可能(可能)运行超过一分钟。

    我进行了一些测试,但请注意我可能以错误的方式进行了测试,但 Play 不会启动 Job 的新实例(如果它已经在运行)。作业完成后,它将在预期时间内运行下一个实例。就好像 Play 将 Jobs 视为“Singletons”,在给定时间只有一个给定类型的活动。

    所以,不,你不需要杀死或检查任何东西。太棒了,不是吗? ;)

    【讨论】:

    • 是的,看起来确实如此!谢谢佩雷。
    【解决方案2】:

    您可以使用ReentrantLock 来防止多个实例同时运行。像这样的:

    @Every("30s")
    public class MyJob extends Job {
      /**
       * Used to avoid running multiple instances of this job simultaneously.
       */
      private static final ReentrantLock runningLock = new ReentrantLock();
    
      @Override
      public void doJob() {
        // sb: try to acquire the lock. if the lock is in use, then just
        // return immediately, because this job is already running.
        // wait a half second before giving up.
        if (!runningLock.tryLock(500, TimeUnit.MILLISECONDS)) {
          // maybe log a message here?
          return;
        }
    
        // IMPORTANT: ANY CODE ADDED TO THIS METHOD MUST BE INSIDE THE TRY OR
        // YOU RUN THE RISK OF FAILING TO RELEASE THE LOCK!
    
        try {
          // perform your job code here...
        } finally {
          // sb: we're finished; release the lock
          runningLock.unlock();
        }
      }
    }
    

    鉴于您的作业每 30 秒运行一次,没有理由在另一个作业正在运行时延迟一个作业 - 只需取消它即可。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-12
      • 1970-01-01
      • 2018-02-28
      • 2015-08-03
      • 1970-01-01
      • 2020-09-24
      • 2021-02-10
      相关资源
      最近更新 更多