Java ScheduledExecutorService的具体使用

2023-05-30 0 3,656

目录

ScheduledExecutorService线程池的特性,也可以实现任务循环执行,可以看作是一个简单地定时任务组件,因为有线程池特性,所以任务之间可以多线程并发执行,互不影响,当任务来的时候,才会真正创建线程去执行

我们在做一些普通定时循环任务时可以用它,比如定时刷新字典常量,只需要不断重复执行即可,这篇文章讲解一下它的用法以及注意事项,不涉及底层原理

注意:我们都知道,在使用线程池的时候,如果我们的任务出现异常没有捕获,那么线程会销毁被回收,不会影响其他任务继续提交并执行,但是在这里,如果你的任务出现异常没有捕获,会导致后续的任务不再执行,所以一定要try...catch

1. 延迟不循环任务schedule方法

schedule(Runnable command, long delay, TimeUnit unit)

参数1:任务
参数2:方法第一次执行的延迟时间
参数3:延迟单位
说明:延迟任务,只执行一次(不会再次执行),参数2为延迟时间

案例说明:

@Component
@Slf4j
public class MineExecutors {
    private final static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(5);
    private final static SimpleDateFormat format = new SimpleDateFormat(\"yyyy-MM-dd HH:mm:sss\");
    @PostConstruct
    public void init() {
        scheduler.schedule(() -> {
            try {
                log.info(\"开始执行...time {}\", format.format(new Date()));
                Thread.sleep(1000);
                log.info(\"执行结束...time {}\", format.format(new Date()));
            } catch (Exception e) {
                log.error(\"定时任务执行出错\");
            }
        }, 5, TimeUnit.SECONDS);
		log.info(\"初始化成功 {}\", format.format(new Date()));
    }
}

可以看到任务执行时间为初始化完成后5s才开始执行,且只执行一次

Java ScheduledExecutorService的具体使用

2. 延迟且循环cheduleAtFixedRate方法

cheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)
参数1:任务
参数2:初始化完成后延迟多长时间执行第一次任务
参数3:任务时间间隔
参数4:单位

方法解释:是以上一个任务开始的时间计时,比如period为5,那5秒后,检测上一个任务是否执行完毕,如果上一个任务执行完毕,则当前任务立即执行,如果上一个任务没有执行完毕,则需要等上一个任务执行完毕后立即执行,如果你的任务执行时间超过5秒,那么任务时间间隔参数将无效,任务会不停地循环执行,由此可得出该方法不能严格保证任务按一定时间间隔执行

错误:任务连续执行案例:

@Component
@Slf4j
public class MineExecutors {
    private final static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(5);
    private final static SimpleDateFormat format = new SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss\");
    @PostConstruct
    public void init() {
        scheduler.scheduleAtFixedRate(() -> {
            try {
                log.info(\"开始执行...time {}\", format.format(new Date()));
                Thread.sleep(3000);
                log.info(\"执行结束...time {}\", format.format(new Date()));
            } catch (Exception e) {
                log.error(\"定时任务执行出错\");
            }
        }, 0, 2, TimeUnit.SECONDS);
        log.info(\"初始化成功 {}\", format.format(new Date()));
    }
}

由上面代码可以看出,任务执行需要3秒,而我们设定的任务时间间隔为2秒,如此就会导致任务连续执行,该方法不能严格保证任务按照规定的时间间隔执行,如果你的任务执行时间可以保证忽略不计,则可以使用该方法,我们可以看到下面日志,上一个任务的执行结束时间与下一个任务的开始时间一致,所以任务连续循环执行了

Java ScheduledExecutorService的具体使用

正确案例:

@Component
@Slf4j
public class MineExecutors {
    private final static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(5);
    private final static SimpleDateFormat format = new SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss\");
    @PostConstruct
    public void init() {
        scheduler.scheduleAtFixedRate(() -> {
            try {
                log.info(\"开始执行...time {}\", format.format(new Date()));
                Thread.sleep(1000);
                log.info(\"执行结束...time {}\", format.format(new Date()));
            } catch (Exception e) {
                log.error(\"定时任务执行出错\");
            }
        }, 0, 3, TimeUnit.SECONDS);
        log.info(\"初始化成功 {}\", format.format(new Date()));
    }
}

可以看到任务以上一次任务的开始时间,按3秒一次的方式执行

Java ScheduledExecutorService的具体使用

3. 严格按照一定时间间隔执行``

scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit);

参数1:任务
参数2:初始化完成后延迟多长时间执行第一次任务
参数3:任务执行时间间隔
参数4:单位
解释:以上一次任务执行结束时间为准,加上任务时间间隔作为下一次任务开始时间,由此可以得出,任务可以严格按照时间间隔执行

案例:

@Component
@Slf4j
public class MineExecutors {
    private final static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(5);
    private final static SimpleDateFormat format = new SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss\");
    @PostConstruct
    public void init() {
        scheduler.scheduleWithFixedDelay(() -> {
            try {
                log.info(\"开始执行...time {}\", format.format(new Date()));
                Thread.sleep(5000);
                log.info(\"执行结束...time {}\", format.format(new Date()));
            } catch (Exception e) {
                log.error(\"定时任务执行出错\");
            }
        }, 0, 3, TimeUnit.SECONDS);
        log.info(\"初始化成功 {}\", format.format(new Date()));
    }
}

由下图日志可以看出,下次任务的开始时间是在上一次任务结束时间+任务时间间隔为准的,严格按照任务时间间隔,规律执行,如果你的任务需要保证严格的时间间隔,可以用该方法启动任务

Java ScheduledExecutorService的具体使用

其他用法与线程池没有差异了,例如ThreadFactory作为参数传入,自定义线程池内线程名称之类的,不多解释了。

资源下载此资源下载价格为1小猪币,终身VIP免费,请先
由于本站资源来源于互联网,以研究交流为目的,所有仅供大家参考、学习,不存在任何商业目的与商业用途,如资源存在BUG以及其他任何问题,请自行解决,本站不提供技术服务! 由于资源为虚拟可复制性,下载后不予退积分和退款,谢谢您的支持!如遇到失效或错误的下载链接请联系客服QQ:442469558

:本文采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可, 转载请附上原文出处链接。
1、本站提供的源码不保证资源的完整性以及安全性,不附带任何技术服务!
2、本站提供的模板、软件工具等其他资源,均不包含技术服务,请大家谅解!
3、本站提供的资源仅供下载者参考学习,请勿用于任何商业用途,请24小时内删除!
4、如需商用,请购买正版,由于未及时购买正版发生的侵权行为,与本站无关。
5、本站部分资源存放于百度网盘或其他网盘中,请提前注册好百度网盘账号,下载安装百度网盘客户端或其他网盘客户端进行下载;
6、本站部分资源文件是经压缩后的,请下载后安装解压软件,推荐使用WinRAR和7-Zip解压软件。
7、如果本站提供的资源侵犯到了您的权益,请邮件联系: 442469558@qq.com 进行处理!

猪小侠源码-最新源码下载平台 Java教程 Java ScheduledExecutorService的具体使用 http://www.20zxx.cn/763167/xuexijiaocheng/javajc.html

猪小侠源码,优质资源分享网

常见问题
  • 本站所有资源版权均属于原作者所有,均只能用于参考学习,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担
查看详情
  • 最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,建议提前注册好百度网盘账号,使用百度网盘客户端下载
查看详情

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务