4 - 线程池 Java内置的线程池 - ScheduledExecutorService
创始人
2024-03-29 07:30:16
0

ScheduledExecutorService

        ScheduledExecutorService是ExecutorService的子接口,具备了延迟运行或定期执行任务的能力。

1、常用获取方式 

注:还是通过 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来创建,且允许在给定延迟后运行命令或者定期地执行任务

2、常用方法

ScheduledFuture schedule(Callable callable, long delay, TimeUnit unit)          

—— 延迟时间单位是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(...)

 3、代码示例

(1)最简单的延迟执行(一个或多个任务)

 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);}
}

结果:

(2)只执行一个任务,但是使其重复执行

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);}
}

结果:

 (3)只执行一个任务,但是使其重复执行

区别于(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秒。

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
【Ctfer训练计划】——(三... 作者名:Demo不是emo  主页面链接:主页传送门 创作初心ÿ...