什么是ScheduledThreadPoolExecutor?
在给定的延迟之后运行任务或者是定期执行任务
本文只简单描述一下怎么使用,不涉及原理和源码,可以简单了解后自己去撸源码。
构造
ScheduledThreadPoolExecutor(int corePoolSize)
ScheduledThreadPoolExecutor(int corePoolSize, RejectedExecutionHandler handler)
ScheduledThreadPoolExecutor(int corePoolSize, ThreadFactory threadFactory)
ScheduledThreadPoolExecutor(int corePoolSize, ThreadFactory threadFactory, RejectedExecutionHandler handler)
ScheduledThreadPoolExecutor方法
类型 | 方法 | 描述 |
---|---|---|
protected <V> RunnableScheduledFuture<V> | decorateTask(Callable<V> callable, RunnableScheduledFuture<V> task) | 修修改或替换用于执行可运行的任务 |
protected <V> RunnableScheduledFuture<V> | decorateTask(Runnable runnable, RunnableScheduledFuture<V> task) | 修改或替换用于执行可运行的任务 |
void | execute(Runnable command) | 零延迟执行命令 |
boolean | getContinueExistingPeriodicTasksAfterShutdownPolicy() | 获取执行程序已关闭是否继续执行现有定期任务的策略 |
boolean | getExecuteExistingDelayedTasksAfterShutdownPolicy() | 获取执行程序已关闭是否执行现有延迟任务的策略 |
BlockingQueue<Runnable> | getQueue() | 返回执行程序使用的任务队列 |
boolean | getRemoveOnCancelPolicy() | 获取在取消时是否应立即从工作队列中删除已取消任务的策略 |
ScheduledFuture<?> | schedule(Runnable command, long delay, TimeUnit unit) | 创建并执行一次操作,该操作在给定延迟后启用 |
ScheduledFuture<?> | scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) | 创建并执行一个周期性操作,该操作在给定的初始延迟后首先启用,然后在给定的时间后再次启用,即第一次是initialDelay后执行,第二次是initialDelay + period后执行,第三次是 initialDelay + period*2 后执行,依次类推 |
ScheduledFuture<?> | scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) | 创建并执行一个周期性动作,该动作在给定的初始延迟后首先启用,然后在一次执行的终止后开始,delay后开始执行下一次 |
void | setContinueExistingPeriodicTasksAfterShutdownPolicy(boolean value) | 设置执行程序关闭是否继续执行现有定期任务的策略 |
void | setExecuteExistingDelayedTasksAfterShutdownPolicy(boolean value) | 设置关闭后执行程序是否也执行现有延迟任务的策略 |
void | setRemoveOnCancelPolicy(boolean value) | 设置取消时任务时是否应立即从工作队列中删除已取消任务的策略 |
void | shutdown() | 启动有序关闭,在该关闭中执行先前提交的任务,但不接受任何新任务 |
List<Runnable> | shutdownNow() | 尝试停止所有正在执行的任务,暂停正在等待的任务的处理,并返回正在等待执行的任务的列表 |
<T> Future<T> | submit(Callable<T> task) | 提交有返回值的Callable任务 |
Future<?> | submit(Runnable task) | 提交有返回值的Runnable任务 |
<T> Future<T> | submit(Runnable task, T result) | 提交有返回值的Callable任务 |
ScheduledThreadPoolExecutor继承自ThreadPoolExecutor,所以也继承了ThreadPoolExecutor方法,ThreadPoolExecutor有哪些方法可以去Java API规范中去查看,也可以到java线程池 - ThreadPoolExecutor中查看。
例子
-
schedule(Runnable command, long delay, TimeUnit unit)
执行没有返回值的Runnable任务
package com.sy.thread.example;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.*;
/**
* Description: thread
*
* @author songyu
*/
public class ScheduledThreadPoolExecutorTest {
public static void main(String[] args) throws Exception {
DateTimeFormatter fmTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//创建线程池
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(2,new ThreadPoolExecutor.AbortPolicy()){
//根据需要重写方法
};
//没有返回值的任务
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
LocalDateTime now = LocalDateTime.now();
System.out.println(now.format(fmTime) + " Runnable开始执行");
}
});
//schedule(Runnable command, long delay, TimeUnit unit)
//延迟2秒执行,没有返回值
LocalDateTime now1 = LocalDateTime.now();
System.out.println(now1.format(fmTime) + " 将Runnable延迟任务加入线程池,一秒后开始执行");
executor.schedule(thread,2, TimeUnit.SECONDS);
}
}
执行结果
2020-07-09 14:48:16 将Runnable延迟任务加入线程池,一秒后开始执行
2020-07-09 14:48:18 Runnable开始执行
-
schedule(Callable<V> callable, long delay, TimeUnit unit)
执行有返回值的Callable任务
package com.sy.thread.example;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.*;
/**
* Description: thread
*
* @author songyu
*/
public class ScheduledThreadPoolExecutorTest2 {
public static void main(String[] args) throws Exception {
DateTimeFormatter fmTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//创建线程池,、
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(2,new ThreadPoolExecutor.AbortPolicy()){
//根据需要重写方法
};
//有返回值的任务
Callable callable = new Callable() {
@Override
public Object call() throws Exception {
LocalDateTime now = LocalDateTime.now();
System.out.println(now.format(fmTime) + " Callable开始执行");
return "hello world";
}
};
//schedule(Callable<V> callable, long delay, TimeUnit unit)
//延迟五秒执行 有返回值
LocalDateTime now2 = LocalDateTime.now();
System.out.println(now2.format(fmTime) + " 将Callable延迟任务加入线程池,一秒后开始执行");
Future future = executor.schedule(callable,5, TimeUnit.SECONDS);
System.out.println("Callable任务返回内容为:" + future.get());
}
}
执行结果
2020-07-09 14:54:49 将Callable延迟任务加入线程池,一秒后开始执行
2020-07-09 14:54:54 Callable开始执行
Callable任务返回内容为:hello world
-
scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)
执行周期性定时任务
command
: 任务
initialDelay
:初次执行的延迟时间
period
: 执行周期时间
第一次是initialDelay
后执行,第二次是initialDelay + period
后执行,第三次是initialDelay + period * 2
,以此类推
package com.sy.thread.example;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* Description: thread
*
* @author songyu
*/
public class ScheduledThreadPoolExecutorTest3 {
public static void main(String[] args) {
DateTimeFormatter fmTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//创建线程池
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(2){
//根据需要重写方法
};
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
LocalDateTime now = LocalDateTime.now();
System.out.println(now.format(fmTime) + " Runnabled周期任务开始执行");
}
});
//scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)
//initialDelay 第一次延迟执行时间
//period 周期时间
//将任务提交到线程池,5秒后执行第一次任务,然后每隔10s执行一次
LocalDateTime now = LocalDateTime.now();
System.out.println(now.format(fmTime) + " 将Runnable周期任务加入线程池,一秒后开始执行");
executor.scheduleAtFixedRate(thread,5,10, TimeUnit.SECONDS);
}
}
执行结果
2020-07-09 15:05:17 将Runnable周期任务加入线程池,一秒后开始执行
2020-07-09 15:05:22 Runnabled周期任务开始执行
2020-07-09 15:05:32 Runnabled周期任务开始执行
2020-07-09 15:05:42 Runnabled周期任务开始执行
2020-07-09 15:05:52 Runnabled周期任务开始执行
2020-07-09 15:06:02 Runnabled周期任务开始执行
2020-07-09 15:06:12 Runnabled周期任务开始执行
2020-07-09 15:06:22 Runnabled周期任务开始执行
2020-07-09 15:06:32 Runnabled周期任务开始执行
......
-
scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)
执行周期性定时任务
command
: 任务
initialDelay
:初次执行的延迟时间
period
: 执行周期时间
第一次是initialDelay
后执行,第二次是在第一次任务执行完成后开始算,period
后执行,第三次是在第二次任务执行完成后开始算,period
后执行,以此类推
package com.sy.thread.example;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Random;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* Description: thread
*
* @author songyu
*/
public class ScheduledThreadPoolExecutorTest4 {
public static void main(String[] args) {
DateTimeFormatter fmTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//创建线程池
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(2){
//根据需要重写方法
};
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
LocalDateTime now = LocalDateTime.now();
System.out.println(now.format(fmTime) + " Runnabled周期任务开始执行");
Random random = new Random();
int randomNumber1 = random.nextInt(10) * 1000;
System.out.println("阻塞" + randomNumber1 + "毫秒");
Thread.sleep(randomNumber1);
LocalDateTime now2 = LocalDateTime.now();
System.out.println(now2.format(fmTime) + " Runnabled周期任务执行结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
//scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)
//initialDelay 第一次延迟执行时间
//period 周期时间
//将任务提交到线程池,5秒后执行第一次任务,第一次执行完成后,10秒后执行下一次,除了第一次执行,后续的执行都是从上一个任务完成后开始算,period时间后执行
LocalDateTime now = LocalDateTime.now();
System.out.println(now.format(fmTime) + " 将Runnable周期任务加入线程池,一秒后开始执行");
executor.scheduleWithFixedDelay(thread,5,10, TimeUnit.SECONDS);
}
}
执行结果
2020-07-09 15:26:04 将Runnable周期任务加入线程池,一秒后开始执行
2020-07-09 15:26:09 Runnabled周期任务开始执行
阻塞8000毫秒
2020-07-09 15:26:17 Runnabled周期任务执行结束
2020-07-09 15:26:27 Runnabled周期任务开始执行
阻塞3000毫秒
2020-07-09 15:26:30 Runnabled周期任务执行结束
2020-07-09 15:26:40 Runnabled周期任务开始执行
阻塞8000毫秒
2020-07-09 15:26:48 Runnabled周期任务执行结束
2020-07-09 15:26:58 Runnabled周期任务开始执行
阻塞9000毫秒
2020-07-09 15:27:07 Runnabled周期任务执行结束
2020-07-09 15:27:17 Runnabled周期任务开始执行
阻塞1000毫秒
2020-07-09 15:27:18 Runnabled周期任务执行结束
2020-07-09 15:27:28 Runnabled周期任务开始执行
......
ScheduledThreadPoolExecutor的execute()和submit()
execute() > schedule(Runnable command, long delay, TimeUnit unit)
submit() > schedule(Callable<V> callable, long delay, TimeUnit unit)
public void execute(Runnable command) {
schedule(command, 0, NANOSECONDS);
}
public Future<?> submit(Runnable task) {
return schedule(task, 0, NANOSECONDS);
}
上面几个简单的例子把ScheduledThreadPoolExecutor几种任务执行的方式都简单的实现了一下,自己可以扩展一下,然后把剩余的方法和学习一下。