Java定时器选择

news/2024/4/20 12:37:29/文章来源:https://blog.csdn.net/weixin_38858037/article/details/128107117

java计时器和死循环哪个好?哪个建议使用?

  1. 计时器性能更好,但是写起来稍微复杂一点。如果是非常短暂的延迟,用死循环也未尝不可。
  2. 一般来说能不用死循环的尽量不用死循环!
  3. 如果你使用的是JDK1.5以上的,可以使用ScheduledThreadPoolExecutor来完成Timer的功能,这个实现起来简单,而且相比timer的缺陷进行了弥补。
  4. 那就看你程序对时间的要求高不高,循环内处理时间长不长了。用死循环的话,它执行的时间不是固定的(每次执行完一次任务时间+睡眠时间)用计时器的话,它是每隔固定时间执行一次。



死循环实现定时器

//死循环方式, 无法保证一直执行, 曾经在Spring Boot上使用这种方式执行定时任务, 运行两个月后不知道哪天这个任务
//所在的线程不执行了, 这条线程的所有异常都catch了, 没有往外抛.
whiletrue{Thread.sleep(time);code;
}



Timer

Timer类提供了一个核心接口,schedule(安排) 指定一个任务交给定时器,在一定时间之后再去执行这个任务~

使用Timer和TimerTask存在一些缺陷:

1.Timer只创建了一个线程。当你的任务执行的时间超过设置的延时时间将会产生一些问题。
2.Timer创建的线程没有处理异常,因此一旦抛出非受检异常,该线程会立即终止。
JDK 5.0以后推荐使用ScheduledThreadPoolExecutor。该类属于Executor Framework,它除了能处理异常外,还可以创建多个线程解决上面的问题。

//Timer和TimerTask的使用
Timer  timer = new Timer();
timer.schedule(new TimerTask() {@Overridepublic void run() {log.e("time:");}
}, 2000, 40);//2000表示第一次执行任务延迟时间,40表示以后每隔多长时间执行一次run里面的任务//取消定时器
timer.cancel();



ScheduledThreadPoolExecutor (强烈建议使用)

ScheduledThreadPoolExecutor,它可另行安排在给定的延迟后运行命令,或者定期执行命令。需要多个辅助线程时,或者要求 ThreadPoolExecutor 具有额外的灵活性或功能时,此类要优于Timer。

参考:
https://blog.csdn.net/cristianoxm/article/details/107640772
https://blog.csdn.net/wenzhi20102321/article/details/78681379

注意:

如果ScheduledThreadPoolExecutor中执行的任务出错抛出异常后,不仅不会打印异常堆栈信息,同时还会取消后面的调度。
https://blog.csdn.net/m0_71777195/article/details/127441811

//ScheduledThreadPoolExecutor的简单使用, 这里先学会简单使用再深入探讨。
//corePoolSize – 保留在池中的线程数,即使它们处于空闲状态,除非设置allowCoreThreadTimeOut
ScheduledThreadPoolExecutor  scheduled = new ScheduledThreadPoolExecutor(2);
//固定频率周期任务scheduleAtFixedRate, 除了这个类型的还有三种类型任务.
scheduled.scheduleAtFixedRate(new Runnable() {@Overridepublic void run() {System.out.println(LocalDateTime.now());try {Thread.sleep(8000);} catch (Exception e) {//TODO 不要往外面抛异常, ScheduledThreadPoolExecutor中执行的任务出错抛出异常后,不仅不会打印异常堆栈信息,同时还会取消后面的调度.e.printStackTrace();}}
}, 0, 40, TimeUnit.MILLISECONDS);
//0表示首次执行任务的延迟时间,40表示每次执行任务的间隔时间,TimeUnit.MILLISECONDS执行的时间间隔数值单位
//间隔单位毫秒:TimeUnit.MILLISECONDS
//间隔单位秒:TimeUnit.SECONDS
//间隔单位分钟:TimeUnit.MINUTES
//间隔单位小时:TimeUnit.HOURS
//间隔单位天:TimeUnit.DAYS//输出结果:
2022-11-29T21:54:22.090508100
2022-11-29T21:54:30.096814100
2022-11-29T21:54:38.102857400
2022-11-29T21:54:46.105952300//这个方法的作用是周期性的调度task执行。task第一次执行的延迟根据initialDelay参数确定,以后每一次执行都间隔period时长。
//如果task的执行时间大于定义的period,那么下一个线程将在当前线程完成之后再执行。整个调度保证不会出现一个以上任务同时执行。//尝试停止所有正在执行的任务,停止等待任务的处理,并返回等待执行的任务列表。从此方法返回后,这些任务将从任务队列中排出(删除)。
//此方法不等待主动执行的任务终止。使用awaitTermination来做到这一点。
//除了尽最大努力停止处理正在执行的任务之外,没有任何保证。此实现通过Thread.interrupt中断任务;任何未能响应中断的任务可能永远不会终止。
scheduled.shutdownNow();

ScheduledThreadPoolExecutor 结构概述

在这里插入图片描述

ScheduledExecutorService接口介绍

ScheduledThreadPoolExecutor直接继承自ScheduledExecutorServiceScheduledThreadPoolExecutor 类的功能也主要体现在ScheduledExecutorService 接口上,它的最主要的功能就是可以对其中的任务进行调度,比如延迟执行、定时执行等等。
ScheduledExecutorService接口定义:

public interface ScheduledExecutorService extends ExecutorService {//提交在给定延迟后启用的一次性任务(无返回值)。public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit);//提交在给定延迟后启用带返回值的一次性任务。public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit);//固定频率周期任务public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit);//固定延迟周期任务public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit);
}
从上面接口定义我们知道,提供了四个方法,下面我们就分别介绍:
  1. schedule (Runnable task, long delay, TimeUnit timeunit) -> 一次性任务(无返回值)
    这个方法的意思是在指定延迟之后运行task。这个方法有个问题,就是没有办法获知task的执行结果。如果我们想获得task的执行结果,我们可以传入一个Callable的实例.
//创建一个线程池,可以安排命令在给定的延迟后运行,或定期执行
//corePoolSize保留在池中的线程数,即使它们处于空闲状态
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);
ScheduledFuture scheduledFuture =
scheduledExecutorService.schedule(new Runnable() {@Overridepublic void run() {System.out.println("Executed!");}},5,TimeUnit.SECONDS);
//有序关闭之前提交的任务,但不会接受新的任务。如果已经关闭,调用没有额外的效果。
//此方法不等待先前提交的任务执行完成, 如果要等待任务执行完成后再关闭使用awaitTermination方法.
scheduledExecutorService.shutdown();
  1. schedule (Callable task, long delay, TimeUnit timeunit) -> 一次性任务(有返回值)
    这个方法与schedule (Runnable task)类似,也是在指定延迟之后运行task,不过它接收的是一个Callable实例,此方法会返回一个ScheduleFuture对象,通过ScheduleFuture我们可以取消一个未执行的task,也可以获得这个task的执行结果。
//创建一个线程池,可以安排命令在给定的延迟后运行,或定期执行
//corePoolSize保留在池中的线程数,即使它们处于空闲状态
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);
ScheduledFuture scheduledFuture =
scheduledExecutorService.schedule(new Callable() {public Object call() {System.out.println("Executed!");return "Called!";}
},5,TimeUnit.SECONDS);
System.out.println("result = " + scheduledFuture.get());
//有序关闭之前提交的任务,但不会接受新的任务。如果已经关闭,调用没有额外的效果。
//此方法不等待先前提交的任务执行完成, 如果要等待任务执行完成后再关闭使用awaitTermination方法.
scheduledExecutorService.shutdown();
  1. scheduleAtFixedRate (Runnable, long initialDelay, long period,TimeUnit timeunit) -> 周期性任务
    这个方法的作用是周期性的调度task执行。task第一次执行的延迟根据initialDelay参数确定,以后每一次执行都间隔period时长。
    如果task的执行时间大于定义的period,那么下一个线程将在当前线程完成之后再执行。整个调度保证不会出现一个以上任务同时执行。
//corePoolSize – 保留在池中的线程数,即使它们处于空闲状态,除非设置allowCoreThreadTimeOut
ScheduledThreadPoolExecutor  scheduled = new ScheduledThreadPoolExecutor(2);
//固定频率周期任务scheduleAtFixedRate, 除了这个类型的还有三种类型任务.
scheduled.scheduleAtFixedRate(new Runnable() {@Overridepublic void run() {System.out.println(LocalDateTime.now());try {Thread.sleep(8000);} catch (Exception e) {//TODO 不要往外面抛异常, ScheduledThreadPoolExecutor中执行的任务出错抛出异常后,不仅不会打印异常堆栈信息,同时还会取消后面的调度.e.printStackTrace();}}
}, 0, 40, TimeUnit.MILLISECONDS);
//0表示首次执行任务的延迟时间,40表示每次执行任务的间隔时间,TimeUnit.MILLISECONDS执行的时间间隔数值单位
//间隔单位毫秒:TimeUnit.MILLISECONDS
//间隔单位秒:TimeUnit.SECONDS
//间隔单位分钟:TimeUnit.MINUTES
//间隔单位小时:TimeUnit.HOURS
//间隔单位天:TimeUnit.DAYS//输出结果:
2022-11-29T21:54:22.090508100
2022-11-29T21:54:30.096814100
2022-11-29T21:54:38.102857400
2022-11-29T21:54:46.105952300//尝试停止所有正在执行的任务,停止等待任务的处理,并返回等待执行的任务列表。从此方法返回后,这些任务将从任务队列中排出(删除)。
//此方法不等待主动执行的任务终止。使用awaitTermination来做到这一点。
//除了尽最大努力停止处理正在执行的任务之外,没有任何保证。此实现通过Thread.interrupt中断任务;任何未能响应中断的任务可能永远不会终止。
scheduled.shutdownNow();
  1. scheduleWithFixedDelay (Runnable, long initialDelay, long period, TimeUnit timeunit) -> 周期性任务
    scheduleWithFixedDelay的参数和scheduleAtFixedRate参数完全一致,它们的不同之处在于对period调度周期的解释。在scheduleAtFixedRate中,period指的两个任务开始执行的时间间隔,也就是当前任务的开始执行时间和下个任务的开始执行时间之间的间隔。而在scheduleWithFixedDelay中,period指的当前任务的结束执行时间到下个任务的开始执行时间。

ScheduledExecutorService的关闭

和ExecutorService类似, 我们在使用完ScheduledExecutorService时需要关闭它。如果不关闭的话,JVM会一直运行直,即使所有线程已经关闭了。关闭ScheduledExecutorService可以使用其继承自ExecutorService接口的shutdown()和shutdownNow()方法,两者的区别请参考【Java线程池 ExecutorService】。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_38950.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高空简易水果采摘装置设计(CAD+proe)

目 录 摘 要 I Abstract II 1 绪论 1 1.1 选题背景及意义 1 1.2研究现状 1 1.2.1国外果园采摘机械现状 1 1.2.2国内果园采摘机械现状 4 1.2.3果园机械存在问题 5 1.2.4果园采摘机械的发展趋势 6 1.3研究主要内容 7 2 高空简易水果采摘装置原理 8 2.1 水果实采摘方式的选择 8 2.…

时间序列:时间序列模型---随机游走过程(The Random Walk Process)

本文是Quantitative Methods and Analysis: Pairs Trading此书的读书笔记。 随机游走过程是一种特殊的ARMA序列。从分子运动到股价波动等现象都被建模为随机游走。 随机游走过程是AR(1)序列&#xff0c;而且,时间序列在时刻的值为&#xff1a; 随机游走过程本质上是到当前时间…

供应双功能螯合剂THP-Mal,THP 马来酰亚胺,CAS:1314929-99-1

一&#xff1a;产品描述 1、名称 THP-Mal THP Maleimide THP 马来酰亚胺 2、CAS编号&#xff1a;1314929-99-1 3、分子式&#xff1a;C44H57N9O13 4、分子量&#xff1a;919.41 5、外观&#xff1a;白色或者灰白色粉末 6、沸点&#xff1a;1389.365.0 C(Predicted) …

Lint-staged自动修复格式错误及小结

文章目录一、背景二、Lint-staged2.1 简介2.2 修改package.json2.3 修改pre-commit2.4 测试三、小结3.1 代码格式规范3.2 Git提交规范一、背景 通过前面几节的介绍&#xff0c;目前想要提交代码&#xff0c;就要保证代码格式规范和提交信息格式规范&#xff0c;特别是pre-subm…

CSS布局的三种方式

绝对定位 绝对定位&#xff1a; ​ 属性&#xff1a;position 值&#xff1a;absolute <style> p.abs{position: absolute;left: 150px;top: 50px; }</style><p >正常文字1</p> <p >正常文字2</p> <p class"abs" >绝对定…

图库 | 图计算的适用场景有哪些?

图计算适用的场景非常广泛。在其肇始的早期阶段&#xff0c;图计算仅限于学术界以及工业界资深的研究机构内部&#xff0c;随着计算机体系架构的发展&#xff0c;图计算也在更广泛的行业和场景中得到应用。按照时间维度我们大体可以把图计算的发展及适用范围分为如下几个阶段&a…

umask 设置文件权限掩码

我们在创建文件或者目录时&#xff0c;看到的权限往往和我们设置的不一样&#xff0c;原因就在于创建文件时要受到 umask的影响。 目录 一、实际情景介绍 二、文件权限掩码 1、什么是权限掩码&#xff1f; 2、权限掩码的作用过程 3、设置权限掩码的两种方式 (1) umask 命…

【SpringCloud】08 分布式事务 seata

文章目录seata一、seata服务端的搭建&#xff08;1&#xff09;下载seata服务端&#xff08;2&#xff09;解压&#xff08;3&#xff09;配置seata的存储方式&#xff08;4&#xff09;创建seata数据库并导入相关表&#xff08;5&#xff09;把mysql的驱动jar放入到seata服务的…

智能运维应用之道,告别企业数字化转型危机

面临的问题及挑战 数据中心发展历程 2000 年中国数据中心始建&#xff0c;至今已经历以下 3 大阶段。早期&#xff1a;离散型数据中心 IT 因以项目建设为导向&#xff0c;故缺乏规划且无专门运维管理体系&#xff0c;此外&#xff0c;开发建设完的项目均是独立运维维护&#…

产品经理要不要考PMP?进化你能力的阶梯!(附:新版考纲及教材)

产品经理和项目经理看起来是毫不相关的两个专业&#xff0c;那么产品经理要不要考PMP呢&#xff1f;其实是非常有必要的。 以前去面试产品经理&#xff0c;HR只会问1个问题&#xff1a;会用axure吗&#xff1f;一开始对产品经理的定义就是设计产品原型的。能设计产品原型&…

Pytest接口测试框架实战项目搭建(三)

一、前言 前面相当于已经讲完整体框架搭建了&#xff0c;本篇主要讲述在实际业务系统的接口请求中&#xff0c;如何运用好该接口自动化测试框架。 二、步骤演示 1、在conf/api_path.py新增需要测试的接口&#xff0c;标黄底色为新加 存放测试接口仅这一个文件就行&#xff0c…

【DevPress】V2.4.3版本发布,增加内容收录管理

DevPress V2.4.3版本于2022年11月10日发版&#xff0c;增加内容收录模块&#xff0c;方便用户内容收录。 一、该版本功能包含 1、新需求 1&#xff09;控制台增加内容收录管理模块&#xff0c;包括收录内容额度管理、自动收录功能、基于内容搜索做收录以及收录内容列表。 - …

[SWPUCTF 2018]SimplePHP

考点&#xff1a;文件上传 试了一下&#xff0c;直接上传php文件是不行的&#xff0c;.user.ini和.htaccess也不行 能看到有提示&#xff0c;flag在f1ag.php中 在查看文件功能处发现get传参&#xff0c;可能是文件包含 尝试包含当前页面 ?filefile.php 得到 <?php h…

测试大老都是怎么理解cookiesession的?

为什么要学习cookie和session呢&#xff1f;若是没有掌握cookie和session的会话机制&#xff0c;就不了解客户端与服务器之间的交互通信原理&#xff0c;也就定位不了产生bug的原因。 cookie与session他们是如何理解的呢&#xff1f; 1、cookie与session区别&#xff1f; co…

STC 51单片机44——实现0.5秒间隔的单向流水灯

// 12MHz晶振 #include "reg52.h" #include "intrins.h" #define time (65536-50000) // 单次定时50ms unsigned char cn; unsigned char temp; void main(void) { cn10; //10*50ms0.5s temp0x7f; TMOD 0x10; //set tim…

springboot+java+vue大学生求职招聘就业岗位匹配推荐系统

目 使用人职匹配推荐系统分为管理员和用户、企业三个权限子模块。 管理员所能使用的功能主要有&#xff1a;首页、个人中心、用户管理、企业管理、岗位信息管理、岗位类型管理、应聘信息管理、应聘状况管理、平台费用管理、系统管理等。 用户可以实现&#xff1b;首页、个人中…

GFS分布式

GFS是什么&#xff1f; 1.1 简单介绍 这个问题说大也大&#xff0c;说小也小。GFS是Google File System的缩写&#xff0c;字面意义上就是Google的文件系统&#xff0c;技术层面上来讲&#xff0c;GFS是Google在2003年前后创建的可扩展分布式文件系统 &#xff0c;用来满足 Goo…

【visual studio】visual studio 2022 无法 复制黏贴

visual studio 2022 cannot copy paste 其他网友也有反馈到微软&#xff1a;VS 2022 Copy and Paste form feature Broken?Copy paste still not fixed in Visual studio 2022表现是突然就无法复制和黏贴了其他的app 就没有这个问题每次都是重启电脑解决。 2022年11月fix 今…

2.1 Redis中SDS的定义

每个sds.h/sdshdr 结构表示一个SDS值 struct sdshdr { //记录 buf 数组中已经使用的字节数量 //等于SDS所保存字符串的长度 int len;//记录buf数组中未使用字节的数量 int free;//字节数组,用于保存字符串 char buf[]; };图2-1 展示了一个SDS 示例: 1、free 属性值为0&#x…

【Spring项目中的Controller理解】

目录 1. 添加依赖 2. 关于异常 1. 添加依赖 首先&#xff0c;需要保障此项目中存在spring-boot-starter-web依赖项&#xff0c;否则&#xff0c;当前项目并不具备Web应用程序开发所需的依赖&#xff01; 提示&#xff1a;spring-boot-starter-web是建立在spring-boot-starte…