Java ScheduledThreadPoolExecutor –使用ExecutorService进行计划
Java中的ScheduledThreadPoolExecutor添加了一些功能,以计划命令在给定延迟后运行或者定期执行。由于ScheduledThreadPoolExecutor是ExecutorService,因此它使用线程池中的线程执行任务。
Java ScheduledThreadPoolExecutor
ScheduledThreadPoolExecutor类是Java Executor框架的一部分,具有Java并发API。此类扩展了ThreadPoolExecutor并实现了ScheduledExecutorService接口。
Java ScheduledThreadPoolExecutor构造函数
ScheduledThreadPoolExecutor(int corePoolSize)–使用给定的核心池大小创建一个新的ScheduledThreadPoolExecutor。
ScheduledThreadPoolExecutor(int corePoolSize,RejectedExecutionHandler处理程序)–使用给定的初始参数创建一个新的ScheduledThreadPoolExecutor。
ScheduledThreadPoolExecutor(int corePoolSize,ThreadFactory threadFactory)–使用给定的初始参数创建一个新的ScheduledThreadPoolExecutor。
ScheduledThreadPoolExecutor(int corePoolSize,ThreadFactory threadFactory,RejectedExecutionHandler处理程序)–使用给定的初始参数创建一个新的ScheduledThreadPoolExecutor。
ScheduledThreadPoolExecutor类的这些构造函数中使用的参数如下:
corePoolSize –要保留在池中的线程数。这些线程数即使处于空闲状态也将始终被创建,除非设置allowCoreThreadTimeOut。
threadFactory –执行程序创建新线程时要使用的工厂。
handler –因达到线程边界和队列容量而被阻止执行时使用的处理程序。
使用执行器工厂方法创建ScheduledThreadPoolExecutor实例
建议使用Executors类提供的静态工厂方法来获取ScheduledThreadPoolExecutor,而不是直接使用上述构造方法之一创建ThreadPoolExecutor的实例。
newSingleThreadScheduledExecutor()–创建一个单线程执行器,该执行器可以安排命令在给定的延迟后运行或者定期执行。
newSingleThreadScheduledExecutor(ThreadFactory threadFactory)–创建一个单线程执行器,该执行器可以计划命令在给定的延迟后运行或者定期执行。
newScheduledThreadPool(int corePoolSize)–创建一个线程池,该线程池可以计划命令在给定的延迟后运行或者定期执行。
newScheduledThreadPool(int corePoolSize,ThreadFactory threadFactory)–创建一个线程池,该线程池可以计划命令在给定延迟后运行或者定期执行。
Java ScheduledThreadPoolExecutor中的调度方法
schedule(Runnable命令,长延迟,TimeUnit单位)–调度Runnable任务以在给定延迟后执行。
schedule(Callable <V>可调用,长延迟,TimeUnit单位)–提交一个Callable任务,以在给定延迟后执行。
scheduleAtFixedRate(Runnable命令,长initialDelay,长周期,TimeUnit单位)–提交一个周期性操作,该操作在给定的初始延迟后首先启用,然后在给定的周期后启用。例如,如果初始延迟为5秒,周期为2秒,则第一个任务将在5秒的延迟后执行,然后每隔2秒执行一次定期执行-initialDelay + period,initialDelay + 2 * period等上。
scheduleWithFixedDelay(Runnable命令,长initialDelay,长延迟,TimeUnit单位)–提交一个周期性操作,该操作在给定的初始延迟后首先启用,然后在给定的执行终止与下一次执行之间具有延迟。例如,如果初始延迟为5秒,周期为2秒,则第一个任务将在5秒钟的延迟后执行,第二个任务将排定在-(第一个任务终止+ 2秒)之后运行。
所有这些调度方法都返回类型ScheduledFuture的结果,该类型通过将Delayed接口与Future接口分开扩展来增加延迟功能。
Java ScheduledThreadPoolExecutor示例–调度Runnable
在此示例中,Executors.newSingleThreadScheduledExecutor()方法用于获取单线程执行程序以进行调度。在计划方法中,延迟设置为5秒,因此应在该延迟之后执行任务。
public class ScheduledThread { public static void main(String[] args) { ScheduledExecutorService scheduledExecutor = Executors.newSingleThreadScheduledExecutor(); System.out.println("Time before execution started- " + new Date()); scheduledExecutor.schedule(new Task(), 5, TimeUnit.SECONDS); scheduledExecutor.shutdown(); } } class Task implements Runnable{ @Override public void run() { System.out.println("Executing task (thread name)- " + Thread.currentThread().getName() + "Executed at- " + new Date()); } }
输出:
Time before execution started- Sat Jan 05 19:11:33 IST 2019 Executing task (thread name)- pool-1-thread-1Executed at- Sat Jan 05 19:11:38 IST 2019
Java ScheduledThreadPoolExecutor的scheduleAtFixedRate()方法示例
本示例说明如何使用scheduleAtFixedRate()方法进行定期调度。 Executors.newScheduledThreadPool(2)方法用于创建两个线程的线程池。请注意,使用awaitTermination()方法可确保计划任务,否则shutdown()方法将不会安排新任务的发生。
public class ScheduledThread { public static void main(String[] args) { ScheduledExecutorService scheduledExecutor = Executors.newScheduledThreadPool(2); System.out.println("Time before execution started- " + new Date()); scheduledExecutor.scheduleAtFixedRate(new Task(), 5, 2, TimeUnit.SECONDS); try { // To terminate task execution after 10 seconds scheduledExecutor.awaitTermination(10, TimeUnit.SECONDS); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } scheduledExecutor.shutdown(); } } class Task implements Runnable{ @Override public void run() { System.out.println("Executing task (thread name)- " + Thread.currentThread().getName() + " Executed at- " + new Date()); // adding delay to keep the thread busy // so that another thread from pool is used try { Thread.sleep(1500); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
输出:
Time before execution started- Sat Jan 05 19:22:13 IST 2019 Executing task (thread name)- pool-1-thread-1 Executed at- Sat Jan 05 19:22:19 IST 2019 Executing task (thread name)- pool-1-thread-1 Executed at- Sat Jan 05 19:22:21 IST 2019 Executing task (thread name)- pool-1-thread-2 Executed at- Sat Jan 05 19:22:23 IST 2019
如我们所见,第一个任务计划在5秒的初始延迟后运行,之后任务计划在2秒的延迟后运行。
Java ScheduledThreadPoolExecutor的scheduleWithFixedDelay()方法示例
本示例说明如何使用scheduleWithFixedDelay()方法进行定期调度。
public class ScheduledThread { public static void main(String[] args) { ScheduledExecutorService scheduledExecutor = Executors.newScheduledThreadPool(2); System.out.println("Time before execution started- " + new Date()); scheduledExecutor.scheduleWithFixedDelay(new Task(), 5, 2, TimeUnit.SECONDS); try { // To terminate task execution after 10 seconds scheduledExecutor.awaitTermination(10, TimeUnit.SECONDS); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } scheduledExecutor.shutdown(); } } class Task implements Runnable{ @Override public void run() { System.out.println("Executing task (thread name)- " + Thread.currentThread().getName() + " Executed at- " + new Date()); // adding delay to keep the thread busy // so that another thread from pool is used try { Thread.sleep(1500); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
输出:
Time before execution started- Sat Jan 05 19:34:13 IST 2019 Executing task (thread name)- pool-1-thread-1 Executed at- Sat Jan 05 19:34:18 IST 2019 Executing task (thread name)- pool-1-thread-1 Executed at- Sat Jan 05 19:34:22 IST 2019
如我们所见,第一个任务计划在5秒的初始延迟后运行,后一个任务计划在上一个任务终止+ 2秒后运行。
使用构造函数的Java ScheduledThreadPoolExecutor示例
到目前为止显示的所有示例都使用Executors类工厂方法,这是获取ScheduledThreadPoolExecutor的推荐方法,但是我们也可以使用ScheduledThreadPoolExecutor类的构造函数。
在下一个示例中,使用构造函数之一创建ScheduledThreadPoolExecutor实例,然后安排可调用对象在延迟3秒后执行。
public class ScheduledThread { public static void main(String[] args) { // creating executor with core pool of 2 threads, default Thread Factory // and handler uses abort policy ScheduledThreadPoolExecutor scheduledExecutor = new ScheduledThreadPoolExecutor(2, Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy()); // Callable implementation Callable<String> c = ()->{ System.out.println("Executed at- " + new Date()); return "Executing task"; }; System.out.println("Time before execution started- " + new Date()); // scheduling tasks with callable as param to be // executed after a delay of 3 Secs ScheduledFuture<String> sf = scheduledExecutor.schedule(c, 3, TimeUnit.SECONDS); try { System.out.println("Value- " + sf.get()); } catch (InterruptedException | ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); } scheduledExecutor.shutdown(); } }
输出:
Time before execution started- Sat Jan 05 19:47:21 IST 2019 Executed at- Sat Jan 05 19:47:24 IST 2019 Value- Executing task