间隔运行 Java 线程
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/426758/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Running a Java Thread in intervals
提问by Epitaph
I have a thread that needs to be executed every 10 seconds. This thread contains several calls (12 - 15) to a database on another server. Additionally, it also accesses around 3 files. Consequently, there will be quite a lot of IO and network overhead.
我有一个需要每 10 秒执行一次的线程。此线程包含对另一台服务器上的数据库的多次调用 (12 - 15)。此外,它还访问大约 3 个文件。因此,会有相当多的 IO 和网络开销。
What is the best strategy to perform the above?
执行上述操作的最佳策略是什么?
One way would be to use the sleep method along with a while loop, but that would be a bad design.
一种方法是将 sleep 方法与 while 循环一起使用,但这将是一个糟糕的设计。
Will a class similar to Timer be helpful in this case? Also, would it be better to create a couple of more threads (one for IO and one for JDBC), instead of having them run in one thread?
在这种情况下,类似于 Timer 的类会有所帮助吗?另外,创建多个线程(一个用于 IO,一个用于 JDBC)而不是让它们在一个线程中运行会更好吗?
采纳答案by Greg Case
I find that a ScheduledExecutorServiceis an excellent way to do this. It is arguably slightly more complex than a Timer
, but gives more flexibility in exchange (e.g. you could choose to use a single thread or a thread pool; it takes units other than solely milliseconds).
我发现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);
回答by jjnguy
Have a look at the Timerand TimerTaskclasses. They are exactly what you want.
You can make a TimerTask implementation that takes your thread object in a constructor.
您可以创建一个 TimerTask 实现,在构造函数中使用您的线程对象。
The run method will then call the threads run method.
然后 run 方法将调用线程的 run 方法。
// Perhaps something like this
Timer t = new Timer();
t.scheduleAtFixedRate(yourTimerTask, 0, 10 * 1000);
// Hopefully your task takes less than 12 seconds
回答by Neil Coffey
One option is to create a ScheduledExecutorService to which you can then schedule your job:
一种选择是创建一个 ScheduledExecutorService,然后您可以在其中安排您的工作:
ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor();
ex.scheduleWithFixedDelay(...);
If you did decide to have multiple threads, then you can create a ScheduledExecutorService with more threads (again, via the Executors class).
如果您确实决定拥有多个线程,那么您可以创建一个包含更多线程的 ScheduledExecutorService(同样,通过 Executors 类)。
In terms of how many threads and what you put in each thread, in terms of performance, I'd say this depends on:
就性能而言,就多少线程以及您在每个线程中放置的内容而言,我认为这取决于:
- for your particular application, can one thread genuinely "do work" while another one is waiting for I/O?
- would your multiple threads ultimately "thrash the same resource" (e.g. read from files in different locations on the same dsk) and thus slow one another down, or would they be simultaneously hitting different resources?
- 对于您的特定应用程序,当另一个线程正在等待 I/O 时,一个线程是否可以真正“工作”?
- 您的多个线程最终会“处理相同的资源”(例如,从同一 dsk 上不同位置的文件读取)并因此减慢彼此的速度,还是会同时访问不同的资源?