我需要在特定时间后执行操作(例如,应用程序启动后30分钟,如果应用程序仍在运行)。
我有什么选择,是否必要意味着会有一个线程“丢失”等待30分钟过去?
理想情况下,在程序启动时,我想做类似以下的事情(有目的地简化),然后再也不用考虑它了:
doIfStillUp( 30, new Runnable() {
....
});
那么我应该如何实施 doIfStillUp(...)?
我应该使用 TimerTask 吗? 执行者框架?
最重要的是(这是为了理解目的):这是否意味着在30分钟内基本没有任何一个线程会丢失空转?
如果有一个线程“无所事事”,这是一个问题吗?如果有10 000个线程(我在这里很滑稽)“什么都不做”怎么办?
请注意,我正在尝试理解“大局”,而不是解决特定问题。
答案 0 :(得分:5)
Executor框架是一个合理的选择。
有一个schedule方法只需要一个可运行的延迟时间。
schedule(Runnable command,
long delay,
TimeUnit unit)
这非常简单。不一定会有线程阻塞等待您的任务。您可以使用上面链接的ScheduledThreadPoolExecutor,使X线程准备好运行计划任务。
您可以想象一个包含任务运行时间的数据结构。单个线程可以观察或设置这些延迟,并且可以在单个线程中潜在地观察数千个。当第一次到期时,它将运行任务。可能使用自己的线程,可能在线程池中使用1个X.当添加新任务或现有任务完成时,它将等待最早到达的时间,然后再次开始整个过程。
答案 1 :(得分:3)
您应该使用Timer。它的javadoc回答了你所有的问题。
每个计时器使用一个线程,但计时器按顺序执行多个任务。计时器任务应该非常短。如果不是,请考虑使用多个计时器。
当然,如果计时器线程没有任何要执行的任务,它将处于空闲状态。空闲线程不消耗任何东西(或几乎任何东西),所以我不担心它。无论如何,你没有太多选择。 10000个线程无所事事当然是一个问题,但这意味着你为每个任务实例化了一个计时器,这是错误的。
答案 2 :(得分:1)
您可以在java.util.Timer
上安排任务。对于所有计时器任务,java.util.Timer
将创建单个计时器线程。
答案 3 :(得分:1)
内置的java计时器是直接的解决方案:http://download.oracle.com/javase/1,5.0/docs/api/java/util/Timer.html#schedule(java.util.TimerTask,long)