ScheduledExecutorService
java.util.concurrent.ScheduledExecutorService是ExecutorService,可以安排任务在延迟后运行,或者在每次执行之间以固定的时间间隔重复执行。任务是由工作线程异步执行的,而不是由将任务交给ScheduledExecutorService的线程异步执行的。
ScheduledExecutorService示例
这是一个简单的" ScheduledExecutorService"示例:
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5); ScheduledFuture scheduledFuture = scheduledExecutorService.schedule(new Callable() { public Object call() throws Exception { System.out.println("Executed!"); return "Called!"; } }, 5, TimeUnit.SECONDS);
首先,创建一个带有5个线程的" ScheduledExecutorService"。然后,创建" Callable"接口的匿名实现,并将其传递给" schedule()"方法。最后两个参数指定" Callable"应在5秒钟后执行。
ScheduledExecutorService实现
由于ScheduledExecutorService是一个接口,因此必须使用它在java.util.concurrent包中的实现才能使用。 ScheduledExecutorService作为以下实现:
- ScheduledThreadPoolExecutor
创建一个ScheduledExecutorService
如何创建" ScheduledExecutorService"取决于我们使用的实现。但是,我们也可以使用Executors工厂类来创建ScheduledExecutorService实例。这是一个例子:
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);
ScheduledExecutorService的用法
一旦创建了" ScheduledExecutorService",就可以通过调用其方法之一来使用它:
- schedule (Callable task, long delay, TimeUnit timeunit)
- schedule (Runnable task, long delay, TimeUnit timeunit)
- scheduleAtFixedRate (Runnable, long initialDelay, long period, TimeUnit timeunit)
- scheduleWithFixedDelay (Runnable, long initialDelay, long period, TimeUnit timeunit)
我将在下面简要介绍每种方法。
时间表(可调用任务,长时间延迟,TimeUnit时间单位)
该方法调度给定的" Callable"以在给定的延迟后执行。
该方法返回一个" ScheduledFuture",可用于在开始执行之前取消任务,或者在执行后获取结果。
这是一个例子:
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5); ScheduledFuture scheduledFuture = scheduledExecutorService.schedule(new Callable() { public Object call() throws Exception { System.out.println("Executed!"); return "Called!"; } }, 5, TimeUnit.SECONDS); System.out.println("result = " + scheduledFuture.get()); scheduledExecutorService.shutdown();
此示例输出:
Executed! result = Called!
计划(可运行任务,长时间延迟,TimeUnit时间单位)
该方法的工作方式类似于以" Callable"作为参数的方法版本,除了" Runnable"无法返回值之外,因此" ScheduledFuture.get()"方法在任务完成时返回null。
scheduleAtFixedRate(可运行,较长的initialDelay,较长的时间段,TimeUnit时间单位)
此方法计划要定期执行的任务。该任务在" initialDelay"之后第一次执行,然后在每次" period"到期时重复执行。
如果给定任务的任何执行均引发异常,则该任务将不再执行。如果没有抛出异常,则该任务将继续执行,直到关闭ScheduledExecutorService为止。
如果任务执行的时间比计划执行之间的时间长,则下一次执行将在当前执行完成后开始。计划的任务一次不会由一个以上的线程执行。
scheduleWithFixedDelay(可运行,长initialDelay,长周期,TimeUnit时间单位)
该方法非常类似于scheduleAtFixedRate()
,除了period
的解释不同。
在" scheduleAtFixedRate()"方法中,"期间"被解释为上一次执行开始到下一次执行开始之间的延迟。
但是,在此方法中,"期间"被解释为上一次执行结束到下一次开始之间的延迟。因此,延迟是在完成执行之间,而不是在执行开始之间。
ScheduledExecutorService关闭
就像ExecutorService一样,ScheduledExecutorService需要在使用完毕后关闭。如果没有,即使所有其他线程都已关闭,它也会保持JVM的运行状态。
我们可以使用从ExecutorService接口继承的Shutdown()或者ShutdownNow()方法关闭ScheduledExecutorService。有关更多信息,请参见ExecutorService关机部分。