根据数据库更新和时间间隔触发Java程序

时间:2014-09-25 15:35:25

标签: java mysql multithreading crontab scheduling

我想要一个启动java程序(相当大的程序)的机制,具体取决于两个条件:

  1. MySQL表中的N个新插入
  2. 每隔5分钟。
  3. 我知道我可以通过crontab或使用Timer或使用存储过程等来完成此操作。

    我的计划是编写一个Java类(我最熟悉),Listener有两个并行线程 - 数据库侦听器和时间监听器线程,每个线程监视其中一个条件。如果有人说,是的,父类将启动一个新线程来运行程序。

    我觉得这将是一个重量级的计划。我还有其他选择吗?

2 个答案:

答案 0 :(得分:1)

使用ScheduledExecutorService

实际上并不是那么大
private static final Runnable PROGRAM_RUNNABLE =  new Runnable() {
    @Override
    public void run() {
        // run the program
    }
}

private ScheduledExecutorService ses = Executors.newScheduledThreadPool(2);

public static void main(String[] args) {
    // database based
    ses.scheduleAtFixedRate(new Runnable() {
        @Override
        public void run() {
            boolean inserted = checkDatabase(); // check the insert in the db
            if(inserted) {
                PROGRAM_RUNNABLE.run();
            }
        }
    }, 0, 1, TimeUnit.MINUTES);

    // time based
    ses.scheduleAtFixedRate(PROGRAM_RUNNABLE, 5, 5, TimeUnit.MINUTES);
}

答案 1 :(得分:1)

写一份工作。让它定期执行。

实际上,你会做一些具有以下性质的事情:

SELECT count(*) FROM table WHERE new = 1;

(或其他)

每隔一秒,5秒,10秒运行一次,根据你的活动看似合理。

当count == N时,运行您的流程。当“自上次运行以来的时间”== 5分钟时,运行您的流程。

这个过程是一样的,你只需要用两个标准来检查它。

这提供了一个优势,即你不会在工作激活TWICE的情况下得到流氓竞争条件(因为工作A发现插入计数恰好是从最后一个工作运行起5分钟)。很少见,但是,竞争条件似乎总是积极地寻找“从未发生过”的“罕见”事件。

至于调度,crontab很容易,因为你不需要维护你的进程,保持你的进程,守护进程等等。

如果你已经在一个长期运行的容器(app server,tomcat等)中运行,那么这个问题已经解决了,你可以利用它。

cron的下行是它的粒度,它最多只运行每分钟。如果时间太长,它对你不起作用。但是,如果没关系,那么拥有一个简单的过程就可以实现真正的价值,这个过程只需点亮,检查并退出。当然,它必须以某种方式持续它的状态(例如,它可以查看作业日志以查看最后一个作业的运行时间。)

在java中,有很多选项:原始线程,休眠,Timers,ScheduledExecutorService,类似于Quartz,EJB Timer bean(如果你运行的是Java EE容器)。

但是,我是KISS粉丝。如果一个cron作业可以做到,那就让它做一次。