【问题标题】:Triggering a Java program based on database updates and time interval根据数据库更新和时间间隔触发 Java 程序
【发布时间】:2014-11-20 11:01:30
【问题描述】:

我想要一种机制,可以根据 2 个条件启动一个 java 程序(相当大的程序):

  1. MySQL 表中的 N 个新插入
  2. 每 5 分钟间隔一次。

我知道我可以通过 crontab 或使用 Timer 或使用存储过程等来做到这一点。

我的计划是编写一个 Java 类(我最熟悉),Listener 有两个并行线程 - Database Listener 和 Time listener 线程,每个线程都监视这些条件之一。如果有人说是,父类将启动一个新线程来运行程序。

我觉得这将是一个重量级的节目。还有其他一些我忽略的选项吗?

【问题讨论】:

  • 是的,我认为你可以使用 Timer 和你的 DAO 层来做到这一点。这是一个算法,只是为了给你一个初步的想法。如果 Timer 向您发送通知或数字或插入模 5 等于 0,您将调用您的执行。
  • @Pracede Thaank 你的信息。

标签: java mysql multithreading crontab scheduling


【解决方案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);
}

【讨论】:

  • 谢谢琼。我会试试这个。
  • 我收到私有静态最终 PROGRAM_RUNNABLE 的语法错误。可能是什么问题?我应该声明该类,使其同时实现 Runnable 和 ScheduledExecutorService,对吗?也不应该是 private static final Runnable PROGRAM_RUNNABLE 吗?
  • 我运行了这个程序。但只有基于时间的启动每 5 分钟运行一次,数据库检查只发生一次。这里没有两个线程吗?能详细点吗?
【解决方案2】:

编写一个作业。让它定期执行。

实际上,您将做一些以下性质的事情:

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

(或其他)

每秒运行一次,5 秒,10 秒,根据你的活动,任何看起来合理的时间。

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

过程是一样的,你只是用这两个标准多检查一下。

这提供了一个优势,即您不会在作业触发 TWICE 时遇到恶意竞争条件(因为作业 A 发现插入计数恰好是从上次作业运行时 5 分钟开始)。罕见,是的,但竞争条件似乎总是积极寻找“从未发生”的“罕见”事件。

至于调度,crontab 很容易,因为您不必维护您的进程、使其保持活动状态、守护进程等等。

如果您已经在长时间运行的容器(应用服务器、tomcat 等)中运行,那么该问题已经解决,您可以利用它。

cron 的缺点是它的粒度,它最多只能每分钟运行一次。如果时间太长,它对你不起作用。但如果没问题,那么有一个简单的过程就很有价值,它只是亮起、检查并退出。当然,它必须以某种方式保持其状态(例如,它可以查看作业日志以查看上次作业的运行时间)。

在 java 中,有很多选项:原始线程、睡眠、Timers、ScheduledExecutorService、Quartz 之类的东西、EJB Timer beans(如果您正在运行 Java EE 容器)。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-13
    • 1970-01-01
    • 2014-11-15
    • 1970-01-01
    • 2022-01-10
    • 2021-06-20
    • 1970-01-01
    • 2021-06-26
    相关资源
    最近更新 更多