java定时器
一、@Scheduled注解
这是基于注解可实现定时任务。
实现:
1、
@EnableScheduling注解到定时方法的类上,或者直接注解到启动类。
2、
@Scheduled注解到定时方法上
@Scheduled有以下参数:
1 @Scheduled(fixedDelay = 3000) //方法执行完成后等待3秒再次执行 2 @Scheduled(fixedRate = 3000) //方法每隔3秒执行一次 3 @Scheduled(initialDelay = 2000,fixedRate = 4000) //延迟2秒执行第一次,之后每隔4秒执行一次 4 @Scheduled(fixedDelayString ="${time.demo}") //可以执行配置文件中的,方法执行完成后等待time.demo再次执行 5 @Scheduled(fixedRateString ="${time.demo}" ) //可以执行配置文件中的,法每隔time.demo执行一次 6 @Scheduled(cron = "0 0,30 0,8 ? * ? ") //cron表达式,方法在每天的8点30分0秒执行,参数为字符串类型
cron表达式,推荐看这篇文章:https://www.jianshu.com/p/1defb0f22ed1
示例:
每隔3秒执行一次。
1 @Component 2 @EnableScheduling 3 public class testScheduled { 4 5 @Scheduled(fixedRate = 3000) 6 public void call(){ 7 System.out.println("每隔3秒打印一次"); 8 } 9 }
优点:简单,只需要两个注解即可
缺点:参数和方法都必须写到代码里面
二、Timer().schedule创建任务
直接上示例,2秒后执行第一次,然后每隔4秒执行一次。
1 @Component 2 public class testTimer { 3 { 4 doTimer(); 5 } 6 public void doTimer(){ 7 //创建timer对象 8 Timer timer = new Timer(); 9 //创建TimerTask对象 10 TimerTask timerTask = new TimerTask() { 11 //重写run方法,就是具体定时做什么事情 12 @Override 13 public void run() { 14 System.out.println(new Date().toString()); 15 } 16 }; 17 //timer来执行timerTask 18 timer.schedule(timerTask,2000,4000); 19 } 20 }
几个概念:
Timer:即定时器,为java自带的工具类,提供定时执行任务的相关功能
timer有3个核心方法:
1、添加任务(6种)
schedule(TimerTask task, long delay):指定任务task,在delay毫秒延迟后执行 schedule(TimerTask task, Date time):指定任务task,在time时间点执行一次 schedule(TimerTask task, long delay, long period):指定任务task,延迟delay毫秒后执行第一次,并在之后每隔period毫秒执行一次 schedule(TimerTask task, Date firstTime, long period):指定任务task,在firstTime的时候执行第一次,之后每隔period毫秒执行一次 scheduleAtFixedRate(TimerTask task, long delay, long period):作用与schedule一致 scheduleAtFixedRate(TimerTask task, Date firstTime, long period):作用与schedule一致 实际上最后都会使用sched(TimerTask task, long time, long period),即指定任务task,在time执行第一次,之后每隔period毫秒执行一次 schedule使用系统时间计算下一次,即System.currentTimeMillis()+period 而scheduleAtFixedRate使用本次预计时间计算下一次,即time + period 对于耗时任务,两者区别较大,请按需求选择,瞬时任务无区别。
2、取消任务方法:cancel(),会将任务队列清空,并堵塞线程,且不再能够接受任务(接受时报错),并不会销毁本身的实例和其内部的线程。
3、净化方法:purge(),净化会将队列里所有被取消的任务移除,对剩余任务进行堆排序,并返回移除任务的数量。
TimerTask:实际上就是一个Runnable而已,继承Runnable并添加了几个自定义的参数和方法,说白了就是在这里面写定时的具体方法。
TaskQueue:即任务队列,Timer生产任务,然后推到TaskQueue里存放,等待处理,被处理掉的任务即被移除掉。
注:TaskQueue
实质上只有一个长度为128的数组用于存储TimerTask
、一个int型变量size表示队列长度、以及对这两个数据的增删改查。
TimerThread:即定时器线程,线程会共享TaskQueue里面的数据,TimerThread会对TaskQueue里的任务进行消耗。
注:TimerThread
实际上就是一个Thread
线程,会不停的监听TaskQueue
,如果队列里面有任务,那么就执行第一个,并将其删除(先删除再执行)。
三、线程
1、通过线程的sleep来造成延时的效果
示例1:thread + runnable
1 @Component 2 public class testThreadAndRunnable { 3 4 private Integer count = 0; 5 6 public testThreadAndRunnable() { 7 test1(); 8 } 9 public void test1() { 10 new Thread(() -> { 11 while (count < 10) { 12 System.out.println(new Date().toString() + ": " + count); 13 count++; 14 try { 15 Thread.sleep(3000); 16 } catch (InterruptedException e) { 17 e.printStackTrace(); 18 } 19 } 20 }).start(); 21 } 22 }
示例2:线程池 + runnable
1 @Component 2 public class testThreadPool { 3 private static final ExecutorService threadPool = Executors.newFixedThreadPool(5);// 线程池 4 private Integer count = 0; 5 public testThreadPool() { 6 test2(); 7 } 8 public void test2() { 9 threadPool.execute(() -> { 10 while (count < 10) { 11 System.out.println(new Date().toString() + ": " + count); 12 count++; 13 try { 14 Thread.sleep(3000); 15 } catch (InterruptedException e) { 16 e.printStackTrace(); 17 } 18 } 19 }); 20 } 21 }
2、使用ScheduledTask + runnable
示例:
@Component public class testScheduledTask { private Integer count = 0; @Autowired private TaskScheduler taskScheduler; public testScheduledTask(TaskScheduler taskScheduler) { this.taskScheduler = taskScheduler; test4(); test5(); test6(); } //设置间隔时间,每2秒执行一次 public void test4() { taskScheduler.scheduleAtFixedRate(() -> { System.out.println(new Date().toString() + ": " + count+"设置间隔时间2秒"); count++; }, 2000); } //可以用Cron表达式,每天凌晨1点执行 public void test5() { taskScheduler.schedule(() -> { System.out.println(new Date().toString() + ": " + count+"凌晨1点执行"); count++; }, new CronTrigger("0 0 1 * * ?")); } //设置间隔时间,每5.5秒执行一次 public void test6() { taskScheduler.scheduleAtFixedRate(() -> { System.out.println(new Date().toString() + ": " + count+"设置间隔时间5.5秒"); count++; }, 5500); } }
四、Quartz
1、导入Quartz的jar包
<dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.3.2</version> </dependency>
2、实现的整体结构
2.1、创建定时任务对象的Job
//创建定时任务的对象 public class MyQuartz implements Job { @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { Date date = new Date(); String format = new SimpleDateFormat("yy-MM-dd HH-mm-ss").format(date); System.out.println("======响应时间为:"+format); } }
2.2、创建执行类
@Component public class MySchedule { public MySchedule() throws SchedulerException { doQ(); } public void doQ() throws SchedulerException { //1、调度器Scheduler的创建 Scheduler scheduler = new StdSchedulerFactory().getScheduler(); //2、创建JobDetail实例,并绑定执行类 JobDetail job = JobBuilder.newJob(MyQuartz.class).withIdentity("Quartz1", "QuartzGroup1").build(); //3、构建Trigger实例 CronTrigger build = TriggerBuilder.newTrigger().withIdentity("Trigger1", "QuartzTrigger1") .startNow() .withSchedule(CronScheduleBuilder.cronSchedule("2/3 * * * * ? *")) .build(); //4、执行Quartz scheduler.scheduleJob(job,build); scheduler.start(); }
corn表达式生成地址:https://cron.qqe2.com/
上述corn表达式指,2秒后开始执行,每3秒执行一次。
2.3、可以通过一些延时操作来控制任务停止时间
//5.利用TimeUnit实现延时操作 TimeUnit.SECONDS.sleep(30); //6.关闭定时任务 scheduler.shutdown(); System.out.println("定时任务结束!");
Quartz参考博客:https://blog.csdn.net/qq_41011626/article/details/113740186
其他参考博客:(118条消息) 【JAVA定时器】四种常见定时器的原理和简单实现_Echo-YeZi的博客-CSDN博客_java 定时器
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性