Java并发编程:Executors.newScheduledThreadPool
原创大约 3 分钟
Java并发编程:Executors.newScheduledThreadPool
Executors.newScheduledThreadPool
方法用于创建一个固定线程数的定时任务执行器,支持延迟执行和周期性任务调度。
目录
1. 概述
newScheduledThreadPool
创建的执行器特点:
- 固定线程数:核心线程数通过参数指定
- 支持定时任务:
schedule()
:延迟执行scheduleAtFixedRate()
:固定速率周期性执行scheduleWithFixedDelay()
:固定延迟周期性执行
语法:
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)
参数说明:
corePoolSize
:线程池核心线程数
2. 创建定时任务执行器
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2); // 创建含2个线程的定时任务执行器
3. 延迟执行任务
scheduler.schedule(() -> {
System.out.println("任务在5秒后执行");
}, 5, TimeUnit.SECONDS);
输出:
任务在5秒后执行
4. 固定速率周期性任务
// 初始延迟2秒,每3秒执行一次
scheduler.scheduleAtFixedRate(
() -> System.out.println("固定速率任务执行于 " + System.currentTimeMillis()),
2, 3, TimeUnit.SECONDS
);
输出示例:
固定速率任务执行于 1630000000000
固定速率任务执行于 1630000003000
固定速率任务执行于 1630000006000
5. 固定延迟周期性任务
// 初始延迟2秒,每次执行结束后延迟3秒
scheduler.scheduleWithFixedDelay(
() -> {
System.out.println("固定延迟任务执行于 " + System.currentTimeMillis());
try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }
},
2, 3, TimeUnit.SECONDS
);
输出示例:
固定延迟任务执行于 1630000000000
固定延迟任务执行于 1630000004000 (执行耗时1秒 + 延迟3秒)
固定延迟任务执行于 1630000008000 (执行耗时1秒 + 延迟3秒)
6. 完整示例
import java.util.concurrent.*;
class ScheduledTask implements Runnable {
private final String name;
public ScheduledTask(String name) { this.name = name; }
@Override
public void run() {
System.out.printf("任务%s由%s执行于%s%n",
name,
Thread.currentThread().getName(),
System.currentTimeMillis());
}
}
public class SchedulerDemo {
public static void main(String[] args) throws InterruptedException {
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);
// 延迟任务
scheduler.schedule(new ScheduledTask("单次任务"), 5, TimeUnit.SECONDS);
// 固定速率任务
scheduler.scheduleAtFixedRate(
new ScheduledTask("固定速率任务"),
2, 3, TimeUnit.SECONDS
);
// 固定延迟任务
scheduler.scheduleWithFixedDelay(
new ScheduledTask("固定延迟任务"),
2, 3, TimeUnit.SECONDS
);
Thread.sleep(10000);
scheduler.shutdown();
scheduler.awaitTermination(60, TimeUnit.SECONDS);
System.out.println("所有任务完成");
}
}
7. 关闭执行器
// 优雅关闭流程
scheduler.shutdown();
try {
if (!scheduler.awaitTermination(60, TimeUnit.SECONDS)) {
scheduler.shutdownNow();
}
} catch (InterruptedException e) {
scheduler.shutdownNow();
}
8. 总结
- 适用场景:定时任务、心跳检测、周期性数据同步等
- 注意事项:
- 固定速率任务可能因执行时间过长而并发执行
- 固定延迟任务的间隔基于任务结束时间计算
- 始终调用
shutdown()
释放资源
通过合理使用newScheduledThreadPool
,可以轻松实现复杂的定时任务调度需求。