ScheduledExecutorService
ScheduledExecutorService是ExecutorService的子接口,具备了延迟运行或定期执行任务的能力。
(注:还是通过 Executors. 的方式进行调用)
1)static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)
—— 创建一个可重用固定线程数的线程池且允许延迟运行或(重复/)定期执行任务
static ScheduledExecutorService newScheduledThreadPool(int corePoolSize, ThreadFactory threadFactory)
—— 创建一个可重用固定线程数的线程池,且线程池中的所有线程都使用ThreadFactory来创建,且允许延迟运行或定期执行任务
2)static ScheduledExecutorService newSingleThreadScheduledExecutor()
—— 创建一个单线程执行程序,它允许在给定延迟后运行命令或者(重复/)定期地执行任务
static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory)
—— 创建一个单线程执行程序,且线程池中的所有线程都使用ThreadFactory来创建,且允许在给定延迟后运行命令或者定期地执行任务
—— 延迟时间单位是unit,数量是delay的时间后执行callable
ScheduledFuture> schedule(Runnable command, long delay, TimeUnit unit)
—— 延迟时间单位是unit,数量是delay的时间后执行command
下面的方法可以重复执行任务:(两种间隔方式)
ScheduledFuture> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)
—— 延迟时间单位是unit,数量是initialDelay的时间后,每间隔period时间重复执行一次command
ScheduledFuture> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)
—— 创建并执行一个在给定初始延迟后首次启用的定期操作,随后,在每一次执行终止和下一次执行开始之间都存在给定的延迟(即:同上面一样,也是重复执行,但是,延迟时间是从第一次(仅仅是第一次?还是每次?:每一次)重复/执行完后的时间开始算起的)
示意图:
上面是scheduleAtFixedRate(...),下面是scheduleWithFixedDelay(...)
ScheduledFuture> schedule(Runnable command, long delay, TimeUnit unit)
package com.zhoulz.demo03;import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;/*** 测试ScheduledExecutorService接口中延迟执行任务和重复执行任务的功能*/
public class ScheduledExecutorServiceDemo01 {public static void main(String[] args) {// 1、获取一个具备延迟执行任务的线程池对象ScheduledExecutorService es = Executors.newScheduledThreadPool(3);// 2、创建多个任务对象,提交任务,每个任务延迟2秒执行// (同样,这个任务可以单独创建一个类,也可以通过匿名内部类的方式)// 提交任务用方法,而不是submit()方法了// 下面先提交一个任务//es.schedule(new MyRunnable(666),2, TimeUnit.SECONDS);// 提交多个任务—— 通过for循环for (int i = 1; i <= 10; i++) {es.schedule(new MyRunnable(i),2, TimeUnit.SECONDS);}// 下面这个打印是在main方法中的,不会延迟。// 所以,正常情况是:打印“over”后,延迟2秒后执行任务System.out.println("over");}
}class MyRunnable implements Runnable{private int id;public MyRunnable(int id) {this.id = id;}@Overridepublic void run() {String name = Thread.currentThread().getName();System.out.println(name + "执行了任务:" + id);}
}
结果:
ScheduledFuture> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)
package com.zhoulz.demo03;import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;/*** 测试ScheduledExecutorService接口中延迟执行任务和重复执行任务的功能*/
public class ScheduledExecutorServiceDemo02 {public static void main(String[] args) {// 1、获取一个具备延迟执行任务的线程池对象ScheduledExecutorService es = Executors.newScheduledThreadPool(3, new ThreadFactory() {int n = 1;@Overridepublic Thread newThread(Runnable r) {return new Thread(r,"自定义的线程名zlz:"+ n++);}});// 2、创建多个任务对象,提交任务,每个任务延迟2秒执行// (匿名内部类的方式,见上面)// 下面不再提交多个任务,而是就提交1个任务,并让其重复执行// 初识延迟1秒,间隔2秒es.scheduleAtFixedRate(new MyRunnable2(666),1,2,TimeUnit.SECONDS);// 提交多个任务—— 通过for循环/*for (int i = 1; i <= 10; i++) {es.schedule(new MyRunnable2(i),2, TimeUnit.SECONDS);}*/System.out.println("over");}
}class MyRunnable2 implements Runnable{private int id;public MyRunnable2(int id) {this.id = id;}@Overridepublic void run() {String name = Thread.currentThread().getName();// 模拟任务执行时间1.5秒,这个1.5秒是在间隔时间2秒钟之类的try {Thread.sleep(1500);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(name + "执行了任务:" + id);}
}
结果:
区别于(2),所用的是scheduleWithFixedDelay()方法 —— 来提交任务
ScheduledFuture> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)
同时,获取线程的方式用的是:
(即单线程的,见下面,(2)用的是指定线程newScheduledThreadPool() )
static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) -—— 且所有线程都使用ThreadFactory(线程工厂)来创建
package com.zhoulz.demo03;import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;/*** 测试ScheduledExecutorService接口中延迟执行任务和重复执行任务的功能*/
public class ScheduledExecutorServiceDemo03 {public static void main(String[] args) {// 1、获取一个具备延迟执行任务的线程池对象ScheduledExecutorService es = Executors.newSingleThreadScheduledExecutor( new ThreadFactory() {int n = 1;@Overridepublic Thread newThread(Runnable r) {return new Thread(r,"自定义的线程名zlz:"+ n++);}});// 2、创建多个任务对象,提交任务,每个任务延迟2秒执行// 下面不再提交多个任务,而是就提交1个任务,并让其重复执行// 初识延迟1秒,间隔2秒es.scheduleWithFixedDelay(new MyRunnable3(666),1,2,TimeUnit.SECONDS);System.out.println("over");}
}class MyRunnable3 implements Runnable{private int id;public MyRunnable3(int id) {this.id = id;}@Overridepublic void run() {String name = Thread.currentThread().getName();// 模拟任务执行时间2秒,所以每间隔2+2=4秒后,才会有一次任务输出try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(name + "执行了任务:" + id);}
}
结果:任务输出之间间隔了4秒。