2.定时器

来源:互联网 发布:玉米田间调查数据 编辑:程序博客网 时间:2024/06/09 15:00

一、Timer类和TimerTask类

import java.util.Date;import java.util.Timer;import java.util.TimerTask;/** * JDK1.5以前的定时器 * schedule(TimerTask task, long delay, long period) * task:任务 * dalay:延时,也就是多少时间后会执行 *period:每隔多少秒执行 */public class TraditionalTimerTest1 {public static void main(String[] args) {new Timer().schedule(new TimerTask() {@Overridepublic void run() {System.out.println("bombing!");}}, 5000,3000);while(true){System.out.println(new Date().getSeconds());try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}}

上述代码意思是:5秒之后执行,然后每隔3秒执行

需求:我们需要4秒执行一次,然后2秒执行一次,然后再4秒执行一次,然后再2秒,以此类推....?

import java.util.Date;import java.util.Timer;import java.util.TimerTask;public class TraditionalTimerTest {private static int count = 0;public static void main(String[] args) {class MyTimerTask extends TimerTask{public void run() {count = (count+1)%2;System.out.println("bombing!");new Timer().schedule(new MyTimerTask(),2000+2000*count);}}new Timer().schedule(new MyTimerTask(), 2000);while(true){System.out.println(new Date().getSeconds());try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}}
JDK1.5以前我们使用的是Timer和TimerTask类

二、 Quartz

需求:这项目中,有一部分功能需要实现定时执行。例如用户在登录的时候,连续输错3次密码后,系统会将该用户冻结,不再允许该用户登录系统,等到了晚上零晨时分,再为所有被冻结的用户解冻,这样,用户在第二天又可以正常登录系统了,该怎么实现?

方案:第一时间,想到了JDK自带的Timer和TimerTask类,可经过测试,要想做到精准的定时,还是比较困难的,于是想到了Quartz。

①引用jar包

要使用Quartz,必须要引入以下这几个包:

log4j-1.2.16quartz-2.1.7slf4j-api-1.6.1.jarslf4j-log4j12-1.6.1.jar

这些包都在下载的Quartz包里面包含着,因此没有必要为寻找这几个包而头疼。

创建要被定执行的任务类

这一步也很简单,只需要创建一个实现了org.quartz.Job接口的类,并实现这个接口的唯一一个方法execute(JobExecutionContext arg0) throws JobExecutionException即可。如:

import java.text.SimpleDateFormat;import java.util.Date;import org.quartz.Job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;public class myJob implements Job {public void execute(JobExecutionContext arg0) throws JobExecutionException {SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");System.out.println(format.format(new Date()));}}
创建任务调度,并执行

这一步应该算是最难的一步的,但其实是非常简单的,直接上代码

import static org.quartz.CronScheduleBuilder.cronSchedule; import static org.quartz.JobBuilder.newJob; import static org.quartz.TriggerBuilder.newTrigger;import java.text.SimpleDateFormat;import java.util.Date;import org.quartz.CronTrigger;import org.quartz.JobDetail;import org.quartz.Scheduler;import org.quartz.SchedulerFactory;import org.quartz.impl.StdSchedulerFactory;public class test {public static void main(String[] args) throws Exception {test t = new test();t.go();}public void go() throws Exception{//首先,必须要取得一个Scheduler地引用SchedulerFactory sf = new StdSchedulerFactory();Scheduler sched =sf.getScheduler();//jobs可以在scheduled的sche.start()方法前被调用//job ①将每隔20秒执行一次JobDetail job =newJob(myJob.class).withIdentity("job1", "group1").build(); CronTrigger trigger = newTrigger().withIdentity("trigger1", "group1").withSchedule(cronSchedule("0/20 * * * * ?")).build(); Date ft = sched.scheduleJob(job,trigger);SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");     System.out.println(job.getKey() + " 已被安排执行于: " + sdf.format(ft) + ",并且以如下重复规则重复执行: " + trigger.getCronExpression());     //job ②将每2分钟执行一次,且在该分钟的第15秒    job = newJob(myJob.class).withIdentity("job2", "group1").build();         trigger = newTrigger().withIdentity("trigger2", "group1").withSchedule(cronSchedule("15 0/2 * * * ?")).build();         ft = sched.scheduleJob(job, trigger);         System.out.println(job.getKey() + " 已被安排执行于: " + sdf.format(ft) + ",并且以如下重复规则重复执行: "+ trigger.getCronExpression());         //开始执行,start()方法被调用后,计时器开始工作,计时器允许放入N个job        sched.start();        try {//主线程等待一分钟        Thread.sleep(60L * 1000L);} catch (Exception e) {}        //关闭定时调度,定时器不在工作        sched.shutdown();}}
OK了,Job1和Job2就会被安排为定时执行了。此时程序是可以执行的了,但是可能会输出WARN级别日志,这是因为没有加log4j的配置文件,加上配置文件,就OK了。这里需要说明的地方只有一个,其它的可以直接Copy到您的项目里面。看代码:

CronTrigger trigger = newTrigger().withIdentity("trigger1", "group1").withSchedule(cronSchedule("0/20 * * * * ?")).build(); 
"0/20 * * * * ?"代表什么?这是关键,搞明白这个,Quartz就能帮助你解决大部分的定时执行任务的功能。

说明:
CronTrigger配置格式:
格式: [秒] [分] [小时] [日] [月] [周] [年]

通配符说明: * 表示所有值. 例如:在分的字段上设置 "*",表示每一分钟都会触发。 ? 表示不指定值。使用的场景为不需要关心当前设置这个字段的值。例如:要在每月的10号触发一个操作,但不关心是周几,所以需要周位置的那个字段设置为"?" 具体设置为 0 0 0 10 * ? - 表示区间。例如 在小时上设置 "10-12",表示 10,11,12点都会触发。 , 表示指定多个值,例如在周字段上设置 "MON,WED,FRI" 表示周一,周三和周五触发 / 用于递增触发。如在秒上面设置"5/15" 表示从5秒开始,每增15秒触发(5,20,35,50)。 在月字段上设置'1/3'所示每月1号开始,每隔三天触发一次。 L 表示最后的意思。在日字段设置上,表示当月的最后一天(依据当前月份,如果是二月还会依据是否是润年[leap]), 在周字段上表示星期六,相当于"7"或"SAT"。如果在"L"前加上数字,则表示该数据的最后一个。例如在周字段上设置"6L"这样的格式,则表示“本月最后一个星期五" W 表示离指定日期的最近那个工作日(周一至周五). 例如在日字段上设置"15W",表示离每月15号最近的那个工作日触发。如果15号正好是周六,则找最近的周五(14号)触发, 如果15号是周未,则找最近的下周一(16号)触发.如果15号正好在工作日(周一至周五),则就在该天触发。如果指定格式为 "1W",它则表示每月1号往后最近的工作日触发。如果1号正是周六,则将在3号下周一触发。(注,"W"前只能设置具体的数字,不允许区间"-").


# 序号(表示每月的第几个周几),例如在周字段上设置"6#3"表示在每月的第三个周六.注意如果指定"#5",正好第五周没有周六,则不会触发该配置(用在母亲节和父亲节再合适不过了)


常见示例:


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 手机清除数据后忘了帐号密码怎么办 拼多多改了标题排名降了怎么办 16g的苹果手机内存不够怎么办 魅族手机没电关机充不进电怎么办 淘宝上买电器售后得不到处理怎么办 苏宁易购物流漏送货已签收怎么办 大件包裹快递快递员不送上楼怎么办 滴滴车主提现忘记登录密码怎么办 荣耀6玩游戏不卡但是闪退怎么办 qq扫码允许别人电脑登录怎么办 药店被举卖假药药检局没查到怎么办 苹果手机连接汽车点了不信任怎么办 装修的化妆品柜台与图纸不合怎么办 买手机邮到了是假手机怎么办 京东白条分期还款第一期逾期怎么办 快递电话留错了在派件怎么办 如果在派件途中客户电话有误怎么办 在派件途中客户电话有误怎么办 成立售电公司后供电公司怎么办 新买的洗衣机外壳坏了怎么办 京东过了7天退货怎么办 同款衣服比京东便宜怎么办 国美不让休班还不给加班钱怎么办 在国美电器买贵商品怎么办 给民俗差评老板骂你怎么办 华为p10后置摄像头调黑了怎么办 美图m6手机相机拍照模糊该怎么办 美图t8用久了卡怎么办 美图m4手机开不开机怎么办 比亚迪m6冷凝器散热不好怎么办 深圳市小汽车摇号审核没通过怎么办 扫码开门售货机拿了不给钱怎么办 预付卡办完后对方不愿退款怎么办 海尔88u52显示內存不足怎么办 京东账号绑定的手机好不用了怎么办 京东账号换手机了手机号没变怎么办 京东发票的号和手机对不起来怎么办 京东账号忘记了只有身份证怎么办啊 京东账号手机号换了忘记账号怎么办 新换的卡被注册过京东号怎么办 以旧换新旧的没给商家报案怎么办