java定时器
java的定时器有四种实现方式
- 使用java的timer类,这种方式可以灵活的控制定时器的开启关闭
- 使用线程和线程池的方法,这种方式对于关闭定时器是不优雅的,甚至可能出错
- 使用spring注解来启动定时任务,使用起来简单,但是关闭起来不方便,得配合那些监听器
- 使用quartz框架来解决,很专业,也很重。
简单记录一下这些方式的用法
java Timer
package com.yezi_tool.demo_basic.test;import org.springframework.stereotype.Component;import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;@Component
public class TimerTest {private Integer count = 0;public TimerTest() {testTimer2();}public void testTimer2() {Timer timer = new Timer();MyTask myTask = new MyTask();timer.schedule(myTask, 0, 1000);}private class MyTask extends TimerTask {@Overridepublic void run() {try {//do SomethingSystem.out.println(new Date().toString() + ": " + count);count++;} catch (Exception e) {e.printStackTrace();}}}}
Spring 的@Scheduled
@Component
@EnableScheduling
public class ScheduleTest {private int count = 0;/*** 每3秒钟执行一次*/@Scheduled(cron = "*/3 * * * * ?")public void test1() {System.out.println(count + ":" + (new Date()).toString());count++;}
}
java线程池
直接用线程sleep方法,也可以扩展使用线程池,本质都是不停的循环+sleep
package com.yezi_tool.demo_basic.test;import org.springframework.stereotype.Component;import java.util.Date;@Component
public class ThreadTest {private Integer count = 0;public ThreadTest() {test1();}public void test1() {new Thread(() -> {while (count < 10) {System.out.println(new Date().toString() + ": " + count);count++;try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}}}).start();}
}
ScheduledTask + runnable,使用专门的定时任务线程池,但是关闭不优雅,根据情况使用
package com.yezi_tool.demo_basic.test;import org.springframework.scheduling.TaskScheduler;
import org.springframework.stereotype.Component;import java.util.Date;@Component
public class ThreadTest {private Integer count = 0;private final TaskScheduler taskScheduler;public ThreadTest(TaskScheduler taskScheduler) {this.taskScheduler = taskScheduler;test3();}public void test3() {taskScheduler.scheduleAtFixedRate(() -> {System.out.println(new Date().toString() + ": " + count);count++;}, 3000);}
}
package com.yezi_tool.demo_basic.test;import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;import java.util.Date;@Component
public class ThreadTest {private Integer count = 0;private final TaskScheduler taskScheduler;public ThreadTest(TaskScheduler taskScheduler) {this.taskScheduler = taskScheduler;test4();}public void test4() {taskScheduler.schedule(() -> {System.out.println(new Date().toString() + ": " + count);count++;}, new CronTrigger("0 0 1 * * ?"));}
}
Quartz
quartz是一个完整的专门做定时任务的框架,支持分布式,事务等复杂功能,具体结构如下:
- job用来定义任务
- trigger用来设置任务执行时间
- scheduler:用来管理任务的执行,暂停和停止
- 此外重要的监视器功能JobListener、TriggerListener、SchedulerListener,能够监视上面三个类的生命周期
quartz中文说明
quarts英文官网
quarts中文教程
public class HelloJob implements Job {@Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {Object tv1 = context.getTrigger().getJobDataMap().get("t1");Object tv2 = context.getTrigger().getJobDataMap().get("t2");Object jv1 = context.getJobDetail().getJobDataMap().get("j1");Object jv2 = context.getJobDetail().getJobDataMap().get("j2");Object sv = null;try {sv = context.getScheduler().getContext().get("skey");} catch (SchedulerException e) {e.printStackTrace();}System.out.println(tv1+":"+tv2);System.out.println(jv1+":"+jv2);System.out.println(sv);System.out.println("hello:"+LocalDateTime.now());}}public class Test {public static void main(String[] args) throws SchedulerException {//创建一个schedulerScheduler scheduler = StdSchedulerFactory.getDefaultScheduler();scheduler.getContext().put("skey", "svalue");//创建一个TriggerTrigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").usingJobData("t1", "tv1").withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(3).repeatForever()).build();trigger.getJobDataMap().put("t2", "tv2");//创建一个jobJobDetail job = JobBuilder.newJob(HelloJob.class).usingJobData("j1", "jv1").withIdentity("myjob", "mygroup").build();job.getJobDataMap().put("j2", "jv2");//注册trigger并启动schedulerscheduler.scheduleJob(job,trigger);scheduler.start();}}

















