Java Scheduler ScheduledExecutorService ScheduledThreadPoolExecutor示例
欢迎使用Java Scheduler示例。
今天,我们将研究" ScheduledExecutorService"及其实现类" ScheduledThreadPoolExecutor"的示例。
Java Scheduler ScheduledExecutorService
有时我们需要定期或者在特定的延迟后执行任务。
Java提供了Timer类,通过它可以实现此目的,但有时我们需要并行运行类似的任务。
因此,创建多个Timer对象将是系统的开销,并且最好有一个计划任务的线程池。
Java通过实现ScheduledExecutorService接口的ScheduledThreadPoolExecutor类提供了调度线程池实现。
ScheduledExecutorService定义合同方法以安排具有不同选项的任务。
有时,我写了一篇有关Java ThreadPoolExecutor的帖子,其中我在使用Executors类创建线程池。
Executors类还提供了用于创建ScheduledThreadPoolExecutor的工厂方法,我们可以其中指定池中的线程数。
Java Scheduler示例
假设我们有一个简单的Runnable类,如下所示。
WorkerThread.java
package com.theitroad.threads; import java.util.Date; public class WorkerThread implements Runnable{ private String command; public WorkerThread(String s){ this.command=s; } @Override public void run() { System.out.println(Thread.currentThread().getName()+" Start. Time = "+new Date()); processCommand(); System.out.println(Thread.currentThread().getName()+" End. Time = "+new Date()); } private void processCommand() { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } } @Override public String toString(){ return this.command; } }
这是一个简单的Runnable类,大约需要5秒钟才能执行其任务。
让我们看一个简单的示例,在该示例中,我们将安排工作线程在延迟10秒后执行。
我们将使用Executors类的newScheduledThreadPool(int corePoolSize)方法返回ScheduledThreadPoolExecutor实例。
这是Executors类的代码片段。
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { return new ScheduledThreadPoolExecutor(corePoolSize); }
以下是我们使用ScheduledExecutorService
和ScheduledThreadPoolExecutor
实现的Java Scheduler示例程序。
package com.theitroad.threads; import java.util.Date; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class ScheduledThreadPool { public static void main(String[] args) throws InterruptedException { ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5); //schedule to run after sometime System.out.println("Current Time = "+new Date()); for(int i=0; i<3; i++){ Thread.sleep(1000); WorkerThread worker = new WorkerThread("do heavy processing"); scheduledThreadPool.schedule(worker, 10, TimeUnit.SECONDS); } //add some delay to let some threads spawn by scheduler Thread.sleep(30000); scheduledThreadPool.shutdown(); while(!scheduledThreadPool.isTerminated()){ //wait for all tasks to finish } System.out.println("Finished all threads"); } }
当我们在Java Scheduler示例程序之上运行时,我们得到以下输出,该输出确认任务正在以10秒的延迟运行。
Current Time = Tue Oct 29 15:10:03 IST 2013 pool-1-thread-1 Start. Time = Tue Oct 29 15:10:14 IST 2013 pool-1-thread-2 Start. Time = Tue Oct 29 15:10:15 IST 2013 pool-1-thread-3 Start. Time = Tue Oct 29 15:10:16 IST 2013 pool-1-thread-1 End. Time = Tue Oct 29 15:10:19 IST 2013 pool-1-thread-2 End. Time = Tue Oct 29 15:10:20 IST 2013 pool-1-thread-3 End. Time = Tue Oct 29 15:10:21 IST 2013 Finished all threads
注意,所有的" schedule()"方法都返回" ScheduledFuture"的实例,我们可以使用它来获取线程状态信息和线程的延迟时间。
ScheduledFuture扩展了Future接口,请在Java Callable Future Example中阅读有关它们的更多信息。
ScheduledExecutorService中还有另外两种方法,它们提供了计划任务定期运行的选项。
ScheduledExecutorService scheduleAtFixedRate(可运行命令,长initialDelay,长周期,TimeUnit单位)
我们可以使用ScheduledExecutorService scheduleAtFixedRate方法来调度任务,使其在初始延迟之后并在给定时间段内运行。
时间段是从池中第一个线程的开始开始的,因此,如果将period指定为1秒,并且线程运行5秒钟,则第一个工作线程完成执行后,下一个线程将开始执行。
例如,如果我们有这样的代码:
for (int i = 0; i < 3; i++) { Thread.sleep(1000); WorkerThread worker = new WorkerThread("do heavy processing"); //schedule task to execute at fixed rate scheduledThreadPool.scheduleAtFixedRate(worker, 0, 10, TimeUnit.SECONDS); }
然后我们将得到如下输出。
Current Time = Tue Oct 29 16:10:00 IST 2013 pool-1-thread-1 Start. Time = Tue Oct 29 16:10:01 IST 2013 pool-1-thread-2 Start. Time = Tue Oct 29 16:10:02 IST 2013 pool-1-thread-3 Start. Time = Tue Oct 29 16:10:03 IST 2013 pool-1-thread-1 End. Time = Tue Oct 29 16:10:06 IST 2013 pool-1-thread-2 End. Time = Tue Oct 29 16:10:07 IST 2013 pool-1-thread-3 End. Time = Tue Oct 29 16:10:08 IST 2013 pool-1-thread-1 Start. Time = Tue Oct 29 16:10:11 IST 2013 pool-1-thread-4 Start. Time = Tue Oct 29 16:10:12 IST 2013
ScheduledExecutorService scheduleWithFixedDelay(可运行命令,长initialDelay,长延迟,TimeUnit单位)
ScheduledExecutorService scheduleWithFixedDelay方法可用于以初始延迟开始定期执行,然后以给定延迟执行。
延迟时间是从线程完成执行的时间开始。
因此,如果我们有如下代码:
for (int i = 0; i < 3; i++) { Thread.sleep(1000); WorkerThread worker = new WorkerThread("do heavy processing"); scheduledThreadPool.scheduleWithFixedDelay(worker, 0, 1, TimeUnit.SECONDS); }
然后我们将得到如下输出。
Current Time = Tue Oct 29 16:14:13 IST 2013 pool-1-thread-1 Start. Time = Tue Oct 29 16:14:14 IST 2013 pool-1-thread-2 Start. Time = Tue Oct 29 16:14:15 IST 2013 pool-1-thread-3 Start. Time = Tue Oct 29 16:14:16 IST 2013 pool-1-thread-1 End. Time = Tue Oct 29 16:14:19 IST 2013 pool-1-thread-2 End. Time = Tue Oct 29 16:14:20 IST 2013 pool-1-thread-1 Start. Time = Tue Oct 29 16:14:20 IST 2013 pool-1-thread-3 End. Time = Tue Oct 29 16:14:21 IST 2013 pool-1-thread-4 Start. Time = Tue Oct 29 16:14:21 IST 2013