Java Scheduler ScheduledExecutorService ScheduledThreadPoolExecutor示例

时间:2020-02-23 14:36:49  来源:igfitidea点击:

欢迎使用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);
}

以下是我们使用ScheduledExecutorServiceScheduledThreadPoolExecutor实现的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