java实现定时任务的三种方法,java的定时任务怎么运行的
00-1010前言TimetasksTimetaskschedulexecutorservicespring任务结束
目录
开发的系统中过程,会有如下的需求:
早上生成订单统计,定时推送文章,发邮件,每5分钟动态抓取数据,更新数据,每晚定时统计用户收入,推送给用户.通常这些需求都是通过定时任务来实现的,列举了java中一些常用的定时任务框架。
前言
00-1010自从我们开始学习java,第一次实现定时任务是TimeTask,Timer使用TaskQueue的类来存储定时任务,这是一个基于最小堆实现的优先级队列。TaskQueue会根据任务之间的距离和下一次执行时间对任务进行排序,以保证堆顶的任务先执行。
实例代码:
public static void main(string[]args){ timertask task=new timertask(){ public void run(){ system . out . println( current time 3360 new date() n thread name 3360 thread . current thread()。getname()));} };Timer timer=新定时器( Timer );长延时=5000Ltimer.schedule(任务,延迟);System.out.println(当前时间3360 newdate () n 线程名称3360 thread.currentthread()。getname()));}运行结果:
当前时间: wedapr 06 22:05336004 CST 2022n线程名称: main当前时间: wedapr 06 2233605336009 CST 2022n线程名称: Timer副本代码从结果中可以看出,5秒后执行了预定任务。
缺点:
TimeTask只能串行执行任务,一旦某个任务耗时过长,就会影响其他任务的执行。如果有异常,任务会直接停止。随着时间的推移,java的技术也在不断更新。鉴于TimeTask的短缺,出现了ScheduledExecutorService来代替TimeTask。
00-1010 scheduledexecutorservice是一个有多个实现类的接口,常用的是ScheduledThreadPoolExecutor。ScheduledThreadPoolExecutor本身就是一个线程池,使用DelayQueue作为任务队列,支持任务的并发执行。
实例代码:
public static void main(String[]args)抛出interrupted exception { ScheduledExecutorService executorService=executors . newscheduledthreadpool(3);//执行任务3360 Executorservice。ScheduleAtFixedRate()-{ system . out . println( Execute task: new Date(),线程名3360 thread.currentthread()。getname())每10秒一次;},1,10,时间单位。秒);}缺点:
尽量避免以Executors的方式创建线程池,因为jdk自己的线程池内部使用的队列比较大,容易出现OOM。定时任务是基于JVM的单内存形式,一旦重启就消失了。不能支持cron表达式实现丰富的定时任务。
00-1010学完Spring,开始用Sprin。
g 自带的Task。Spring Framework 自带定时任务,提供了 cron 表达式来实现丰富定时任务配置。
实例代码:
@EnableScheduling@Componentpublic class SpringTask{ private Logger logger = LoggerFactory.getLogger(SpringTask.class); private static final SimpleDateFormat dateFormat = new SimpleDateFormat( "HH:mm:ss"); /** * fixedRate:固定速率执行。每5秒执行一次。 */ @Scheduled(fixedRate = 5000) public void invokeTaskWithFixedRate() { logger.info("Fixed Rate Task : Current Time is {}", dateFormat.format(new Date())); } /** * fixedDelay:固定延迟执行。距离上一次调用成功后2秒才执。 */ @Scheduled(fixedDelay = 2000) public void invokeTaskWithFixedDelay() { try { TimeUnit.SECONDS.sleep(3); logger.info("Fixed Delay Task : Current Time is {}", dateFormat.format(new Date())); } catch (InterruptedException e) { logger.error("invoke task error",e); } } /** * initialDelay:初始延迟。任务的第一次执行将延迟5秒,然后将以5秒的固定间隔执行。 */ @Scheduled(initialDelay = 5000, fixedRate = 5000) public void invokeTaskWithInitialDelay() { logger.info("Task with Initial Delay : Current Time is {}", dateFormat.format(new Date())); } /** * cron:使用Cron表达式,每隔5秒执行一次 */ @Scheduled(cron = "0/5 * * * * ? ") public void invokeTaskWithCronExpression() { logger.info("Task Cron Expression: Current Time is {}", dateFormat.format(new Date())); }}
执行结果:
2022-04-06 23:06:20.945 INFO 14604 --- [ scheduling-1] com.fw.task.SpringTask : Task Cron Expression: Current Time is 23:06:202022-04-06 23:06:22.557 INFO 14604 --- [ scheduling-1] com.fw.task.SpringTask : Task with Initial Delay : Current Time is 23:06:222022-04-06 23:06:22.557 INFO 14604 --- [ scheduling-1] com.fw.task.SpringTask : Fixed Rate Task : Current Time is 23:06:222022-04-06 23:06:25.955 INFO 14604 --- [ scheduling-1] com.fw.task.SpringTask : Fixed Delay Task : Current Time is 23:06:252022-04-06 23:06:25.955 INFO 14604 --- [ scheduling-1] com.fw.task.SpringTask : Task Cron Expression: Current Time is 23:06:252022-04-06 23:06:27.555 INFO 14604 --- [ scheduling-1] com.fw.task.SpringTask : Task with Initial Delay : Current Time is 23:06:272022-04-06 23:06:27.556 INFO 14604 --- [ scheduling-1] com.fw.task.SpringTask : Fixed Rate Task : Current Time is 23:06:27
@EnableScheduling需要开启定时任务,@Scheduled(cron = "0/5 * * * * ?")配置定时任务的规则。cron表达式支持丰富定时任务配置,不熟悉的的可以查看
优点:
使用简单方便,支持各种复杂的定时任务配置
缺点:
基于单机形式定时任务,一旦重启定时任务就消失了。定时任务默认是单线程执行任务,如果需要并行执行需要开启@EnableAsync。没有统一的图形化任务调度的管理,无法控制定时任务
结语
任何技术的出现都有它的价值,技术没有最好的,只有最合适的。我们要针对不同的需求选择最合适的技术,切莫过度架构设计。本文讲解了单机环境实现定时任务的技术,
到此这篇关于Java单机环境实现定时任务技术的文章就介绍到这了,更多相关Java定时任务框架内容请搜索盛行IT以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。