最近我收到一个面试问题:
有一种情况是,一个线程在一个小时内执行批处理操作,你会使用执行器框架还是普通线程?为什么?
我很困惑。
由于只有一个线程,所以不需要执行器服务。我可以用while
和CCD_ 2。
while(1)
{
// do task
// t1.sleep(60*60*1000);
}
虽然有一个ScheduleExecutorService为日程安排提供了这么多方法?
最好的方法是什么?
上面的解决方案的问题是,如果你的任务需要59分钟,那么你的线程将花费59分钟执行你的任务,然后睡一个小时。因此,您将每(几乎)2小时调用一次任务。
如果您使用scheduled executor框架,那么它将在的每小时调用您的任务(无论需要多长时间)。还要注意的是,它可以处理任务执行时间超过一个小时的场景(无论是设计的还是意外的)。您可以选择并行启动第二个任务,或者跳过后续调用。
我通常会使用executor框架。它提供了许多有用的功能,并且您可以封装您的任务,使它们不必在计划的执行器中运行,而是在任何执行器中都必须运行。
在这种情况下,普通线程与执行器服务是错误的二分法。真正的问题应该是,使用旧的Timer
与新的ScheduledExecutorService
。即使在Java 1.2上,尝试使用纯线程重新实现任务调度也是完全多余的。
答案将再次是";使用执行器服务";。它更方便、更灵活、更可扩展。随着应用程序的发展,使其适应越来越困难的需求几乎是微不足道的。
计时器==旧计时器
实际上,在今天的Java中,线程与定时器与执行器服务的整个问题都应该被抨击。使用ExecutorService,你就不会出错;使用任何其他选项,你就会把自己画成一个角落。
我认为这取决于您需要什么。
ScheduleExecutiorService有一些有用的功能,如
scheduleAtFixedRate:无论您的任务将运行多长时间,此调用都将确保您的任务以固定速率运行。例如,心跳
scheduleWithFixedDelay:这个会在你的任务完成后添加一个延迟,例如,一些干净的工作。
ScheduledExecutitorService应该是一个不错的选择,因为您不需要编写代码来定期调度tak。使用经过良好测试的框架比编写自己的框架要好。您可以依靠ScheduledExecutiorService定期执行配置的任务。它将为您节省编写类似功能的时间和精力。
使用ScheduledExecutiorService的其他好处是,您可以取消任务,完成任务后可以获得任务的状态,等等。
ScheduleExecutorService通过返回ScheduledFuture为您提供了一种检查/取消执行的方法。如果使用单个线程,则必须自己实现。