4

我正在使用 JDBC,需要不断检查数据库以防止更改值。

我目前拥有的是一个无限循环运行,内部循环迭代一个变化的值,并且每次迭代都检查数据库。

public void runInBG() { //this method called from another thread
    while(true) {
     while(els.hasElements()) {
      Test el = (Test)els.next();
       String sql = "SELECT * FROM Test WHERE id = '" + el.getId() + "'";
       Record r = db.getTestRecord(sql);//this function makes connection, executeQuery etc...and return Record object with values
       if(r != null) {
         //do something
       }
     }
    }
}

我认为这不是最好的方法。

我在想的另一种方式是相反的,继续迭代数据库。

更新

感谢您提供有关计时器的反馈,但我认为它不会解决我的问题。一旦数据库中发生更改,我需要根据更改的值(示例代码中的“els”)几乎立即处理结果。

即使数据库没有改变,它仍然必须不断检查变化的值。

更新 2

好的,对于任何对答案感兴趣的人,我相信我现在有了解决方案。基本上解决方案不是为此使用数据库。加载、更新、添加等……只需要从数据库到内存。这样您就不必经常打开和关闭数据库,您只需在对数据库进行更改时处理数据库,并将这些更改反映到内存中,并且只处理当时内存中的任何内容。当然,这会占用更多内存,但性能在这里是绝对关键。

至于定期的“计时器”答案,我很抱歉,但这根本不对。没有人回应使用计时器将如何解决这种特殊情况的原因。

但是再次感谢您的反馈,尽管如此,它仍然很有帮助。

4

6 回答 6

3

另一种可能性是使用ScheduledThreadPoolExecutor.

您可以实现一个Runnable包含您的逻辑并将其注册到ScheduledExecutorService如下:

ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(10);
executor.scheduleAtFixedRate(myRunnable, 0, 5, TimeUnit.SECONDS);

上面的代码在它的池中创建了一个ScheduledThreadPoolExecutor有 10 个线程的线程,并且会Runnable注册一个在 5 秒内立即开始运行的线程。


要安排您的可运行文件,您可以使用:

scheduleAtFixedRate

创建并执行一个周期性动作,该动作在给定的初始延迟后首先启用,随后在给定的周期内启用;也就是说,执行将在 initialDelay 之后开始,然后是 initialDelay+period,然后是 initialDelay + 2 * period,依此类推。

scheduleWithFixedDelay

创建并执行一个周期性操作,该操作首先在给定的初始延迟之后启用,随后在一个执行的终止和下一个执行的开始之间具有给定的延迟。


在这里您可以看到 的优点ThreadPoolExecutor,以查看它是否符合您的要求。我建议这个问题:Java Timer vs ExecutorService?也是为了做出正确的决定。

于 2013-05-14T05:57:41.320 回答
1

保留while(true)在里面runInBG()是个坏主意。你最好去掉那个。相反,您可以拥有一个调度程序/计时器(使用TimerTimerTask),它会runInBG()定期调用并检查数据库中的更新。

于 2013-05-14T05:47:00.637 回答
1

你可以使用计时器--->

Timer timer = new Timer("runInBG");

    //Taking an instance of class contains your repeated method.
    MyClass t = new MyClass();

    timer.schedule(t, 0, 2000);
于 2013-05-14T05:51:31.657 回答
0

正如您在上面的评论中所说,如果应用程序控制更新和插入,那么您可以创建一个框架,通知“BG”线程或进程有关数据库的更改。通知可以通过网络通过 JMS 或使用观察者模式的内部 VM 或本地和远程通知。

你可以有通用的通知消息(它可以是本地通知的类或远程通知的短信)

<Notification> 
  <Type>update/insert</Type>
  <Entity>
     <Name>Account/Customer</Name>
     <Id>id</Id>
  <Entity> 
</Notification>
于 2013-05-14T06:33:37.363 回答
0

为了避免“忙循环”,我会尝试使用触发器。H2 还支持DatabaseEventListener API,这样您就不必为每个表创建触发器。

这可能并不总是有效,例如,如果您使用远程连接。

于 2013-05-15T07:40:04.327 回答
0

更新 2

好的,对于任何对答案感兴趣的人,我相信我现在有了解决方案。基本上解决方案不是为此使用数据库。加载、更新、添加等……只需要从数据库到内存。这样您就不必经常打开和关闭数据库,您只需在对数据库进行更改时处理数据库,并将这些更改反映到内存中,并且只处理当时内存中的任何内容。当然,这会占用更多内存,但性能在这里是绝对关键。

于 2013-05-17T17:11:58.790 回答