19

我有一个需要每 10 秒执行一次的线程。此线程包含对另一台服务器上的数据库的多次调用 (12 - 15)。此外,它还访问大约 3 个文件。因此,会有相当多的 IO 和网络开销。

执行上述操作的最佳策略是什么?

一种方法是使用 sleep 方法和 while 循环,但这是一个糟糕的设计。

在这种情况下,类似于 Timer 的类会有所帮助吗?另外,创建多个线程(一个用于 IO,一个用于 JDBC)而不是让它们在一个线程中运行会更好吗?

4

3 回答 3

51

我发现ScheduledExecutorService是一个很好的方法来做到这一点。它可以说比 a 稍微复杂一些Timer,但在交换方面提供了更大的灵活性(例如,您可以选择使用单个线程或线程池;它需要的单位不仅仅是毫秒)。

ScheduledExecutorService executor =
    Executors.newSingleThreadScheduledExecutor();

Runnable periodicTask = new Runnable() {
    public void run() {
        // Invoke method(s) to do the work
        doPeriodicWork();
    }
};

executor.scheduleAtFixedRate(periodicTask, 0, 10, TimeUnit.SECONDS);
于 2009-01-09T01:57:16.613 回答
5

一种选择是创建一个 ScheduledExecutorService ,然后您可以安排您的作业:

ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor();
ex.scheduleWithFixedDelay(...);

如果您确实决定拥有多个线程,那么您可以创建一个具有更多线程的 ScheduledExecutorService(同样,通过 Executors 类)。

就线程数和每个线程中的内容而言,就性能而言,我想说这取决于:

  • 对于您的特定应用程序,一个线程能否真正“工作”而另一个线程正在等待 I/O?
  • 您的多个线程最终会“破坏相同的资源”(例如,从同一个 dsk 上不同位置的文件中读取)并因此减慢彼此的速度,还是它们会同时访问不同的资源?
于 2009-01-09T01:56:56.567 回答
4

看看TimerTimerTask类。它们正是您想要的。

您可以制作一个 TimerTask 实现,该实现将您的线程对象放入构造函数中。

然后 run 方法将调用线程的 run 方法。

// Perhaps something like this
Timer t = new Timer();
t.scheduleAtFixedRate(yourTimerTask, 0, 10 * 1000);
// Hopefully your task takes less than 12 seconds
于 2009-01-09T01:38:42.283 回答