java实现定时任务 Schedule

https://blog.csdn.net/java_2017_csdn/article/details/78060204

1.java定时任务可以借助 java.util.Timer 来实现

[java]

  1. import java.util.Calendar;
  2. import java.util.Date;
  3. import java.util.Timer;
  4. import java.util.TimerTask;
  5. public class Test {
  6.     public static void main(String[] args) {
  7.         //timer1();
  8.         timer2();
  9.         //timer3();
  10.         //timer4();
  11.     }
  12.     // 第一种方法:设定指定任务task在指定时间time执行 schedule(TimerTask task, Date time)
  13.     public static void timer1() {
  14.         Timer timer = new Timer();
  15.         timer.schedule(new TimerTask() {
  16.             public void run() {
  17.                 System.out.println(“——-设定要指定任务——–“);
  18.             }
  19.         }, 2000);// 设定指定的时间time,此处为2000毫秒
  20.     }
  21.     // 第二种方法:设定指定任务task在指定延迟delay后进行固定延迟peroid的执行
  22.     // schedule(TimerTask task, long delay, long period)
  23.     public static void timer2() {
  24.         Timer timer = new Timer();
  25.         timer.schedule(new TimerTask() {
  26.             public void run() {
  27.                 System.out.println(“——-设定要指定任务——–“);
  28.             }
  29.         }, 1000, 1000);
  30.     }
  31.     // 第三种方法:设定指定任务task在指定延迟delay后进行固定频率peroid的执行。
  32.     // scheduleAtFixedRate(TimerTask task, long delay, long period)
  33.     public static void timer3() {
  34.         Timer timer = new Timer();
  35.         timer.scheduleAtFixedRate(new TimerTask() {
  36.             public void run() {
  37.                 System.out.println(“——-设定要指定任务——–“);
  38.             }
  39.         }, 1000, 2000);
  40.     }
  41.     // 第四种方法:安排指定的任务task在指定的时间firstTime开始进行重复的固定速率period执行.
  42.     // Timer.scheduleAtFixedRate(TimerTask task,Date firstTime,long period)
  43.     public static void timer4() {
  44.         Calendar calendar = Calendar.getInstance();
  45.         calendar.set(Calendar.HOUR_OF_DAY, 12); // 控制时
  46.         calendar.set(Calendar.MINUTE, 0);       // 控制分
  47.         calendar.set(Calendar.SECOND, 0);       // 控制秒
  48.         Date time = calendar.getTime();         // 得出执行任务的时间,此处为今天的12:00:00
  49.         Timer timer = new Timer();
  50.         timer.scheduleAtFixedRate(new TimerTask() {
  51.             public void run() {
  52.                 System.out.println(“——-设定要指定任务——–“);
  53.             }
  54.         }, time, 1000 * 60 * 60 * 24);// 这里设定将延时每天固定执行
  55.     }
  56. }

 

2. Java定时任务可以用线程的等待来实现

 

[java]

  1. /**
  2.  * 普通thread
  3.  * 这是最常见的,创建一个thread,然后让它在while循环里一直运行着,
  4.  * 通过sleep方法来达到定时任务的效果。这样可以快速简单的实现,代码如下:
  5.  * @author GT
  6.  *
  7.  */
  8. public class Task1 {
  9.     public static void main(String[] args) {
  10.         // run in a second
  11.         final long timeInterval = 1000;
  12.         Runnable runnable = new Runnable() {
  13.             public void run() {
  14.                 while (true) {
  15.                     // ——- code for task to run
  16.                     System.out.println(“Hello !!”);
  17.                     // ——- ends here
  18.                     try {
  19.                         Thread.sleep(timeInterval);
  20.                     } catch (InterruptedException e) {
  21.                         e.printStackTrace();
  22.                     }
  23.                 }
  24.             }
  25.         };
  26.         Thread thread = new Thread(runnable);
  27.         thread.start();
  28.     }
  29. }

 

3.Java可以用java.util.concurrent.ScheduledExecutorService 来实现定时任务

 

[java]

  1. import java.util.concurrent.Executors;
  2. import java.util.concurrent.ScheduledExecutorService;
  3. import java.util.concurrent.TimeUnit;
  4. /**
  5.  *
  6.  *
  7.  * ScheduledExecutorService是从Java SE5的java.util.concurrent里,做为并发工具类被引进的,这是最理想的定时任务实现方式。
  8.  * 相比于上两个方法,它有以下好处:
  9.  * 1>相比于Timer的单线程,它是通过线程池的方式来执行任务的
  10.  * 2>可以很灵活的去设定第一次执行任务delay时间
  11.  * 3>提供了良好的约定,以便设定执行的时间间隔
  12.  *
  13.  * 下面是实现代码,我们通过ScheduledExecutorService#scheduleAtFixedRate展示这个例子,通过代码里参数的控制,首次执行加了delay时间。
  14.  *
  15.  *
  16.  * @author GT
  17.  *
  18.  */
  19. public class Task3 {
  20.     public static void main(String[] args) {
  21.         Runnable runnable = new Runnable() {
  22.             public void run() {
  23.                 // task to run goes here
  24.                 System.out.println(“Hello !!”);
  25.             }
  26.         };
  27.         ScheduledExecutorService service = Executors
  28.                 .newSingleThreadScheduledExecutor();
  29.         // 第二个参数为首次执行的延时时间,第三个参数为定时执行的间隔时间
  30.         service.scheduleAtFixedRate(runnable, 10, 1, TimeUnit.SECONDS);
  31.     }
  32. }

 

4. 定时任务之-Quartz使用篇

Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的日程序表。Jobs可以做成标准的Java组件或 EJBs。

 

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

序号 说明 是否必填 允许填写的值 允许的通配符
1 0-59 , – * /
2 0-59 , – * /
3 小时 0-23 , – * /
4 1-31 , – * ? / L W
5 1-12 or JAN-DEC , – * /
6 1-7 or SUN-SAT , – * ? / L #
7 empty 或 1970-2099 , – * /

 

通配符说明:
* 表示所有值. 例如:在分的字段上设置 “*”,表示每一分钟都会触发。
? 表示不指定值。使用的场景为不需要关心当前设置这个字段的值。例如:要在每月的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”前只能设置具体的数字,不允许区间”-“).

小提示 ‘L’和 ‘W’可以一组合使用。如果在日字段上设置”LW”,则表示在本月的最后一个工作日触发(一般指发工资 )

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

小提示 周字段的设置,若使用英文字母是不区分大小写的 MON 与mon相同.

 

常用示例:

0 0 12 * * ? 每天12点触发
0 15 10 ? * * 每天10点15分触发
0 15 10 * * ? 每天10点15分触发
0 15 10 * * ? * 每天10点15分触发
0 15 10 * * ? 2005 2005年每天10点15分触发
0 * 14 * * ? 每天下午的 2点到2点59分每分触发
0 0/5 14 * * ? 每天下午的 2点到2点59分(整点开始,每隔5分触发)
0 0/5 14,18 * * ? 每天下午的 2点到2点59分(整点开始,每隔5分触发)每天下午的 18点到18点59分(整点开始,每隔5分触发)
0 0-5 14 * * ? 每天下午的 2点到2点05分每分触发
0 10,44 14 ? 3 WED 3月分每周三下午的 2点10分和2点44分触发
0 15 10 ? * MON-FRI 从周一到周五每天上午的10点15分触发
0 15 10 15 * ? 每月15号上午10点15分触发
0 15 10 L * ? 每月最后一天的10点15分触发
0 15 10 ? * 6L 每月最后一周的星期五的10点15分触发
0 15 10 ? * 6L 2002-2005 从2002年到2005年每月最后一周的星期五的10点15分触发
0 15 10 ? * 6#3 每月的第三周的星期五开始触发
0 0 12 1/5 * ? 每月的第一个中午开始每隔5天触发一次
0 11 11 11 11 ? 每年的11月11号 11点11分触发(光棍节)

经过封装的管理类:

[java]

  1. import java.text.ParseException;
  2. import org.quartz.CronTrigger;
  3. import org.quartz.JobDetail;
  4. import org.quartz.Scheduler;
  5. import org.quartz.SchedulerException;
  6. import org.quartz.SchedulerFactory;
  7. import org.quartz.impl.StdSchedulerFactory;
  8. /**
  9.  * 定时任务管理类
  10.  *
  11.  */
  12. public class QuartzManager {
  13.     private static SchedulerFactory gSchedulerFactory = new StdSchedulerFactory();
  14.     private static String JOB_GROUP_NAME = “EXTJWEB_JOBGROUP_NAME”;
  15.     private static String TRIGGER_GROUP_NAME = “EXTJWEB_TRIGGERGROUP_NAME”;
  16.     /**
  17.      * 添加一个定时任务,使用默认的任务组名,触发器名,触发器组名
  18.      *
  19.      * @param jobName
  20.      *            任务名
  21.      * @param jobClass
  22.      *            任务
  23.      * @param time
  24.      *            时间设置,参考quartz说明文档
  25.      * @throws SchedulerException
  26.      * @throws ParseException
  27.      */
  28.     public static void addJob(String jobName, String jobClass, String time) {
  29.         try {
  30.             Scheduler sched = gSchedulerFactory.getScheduler();
  31.             JobDetail jobDetail = new JobDetail(jobName, JOB_GROUP_NAME, Class.forName(jobClass));// 任务名,任务组,任务执行类
  32.             // 触发器
  33.             CronTrigger trigger = new CronTrigger(jobName, TRIGGER_GROUP_NAME);// 触发器名,触发器组
  34.             trigger.setCronExpression(time);// 触发器时间设定
  35.             sched.scheduleJob(jobDetail, trigger);
  36.             // 启动
  37.             if (!sched.isShutdown()){
  38.                 sched.start();
  39.             }
  40.         } catch (Exception e) {
  41.             e.printStackTrace();
  42.             throw new RuntimeException(e);
  43.         }
  44.     }
  45.     /**
  46.      * 添加一个定时任务
  47.      *
  48.      * @param jobName
  49.      *            任务名
  50.      * @param jobGroupName
  51.      *            任务组名
  52.      * @param triggerName
  53.      *            触发器名
  54.      * @param triggerGroupName
  55.      *            触发器组名
  56.      * @param jobClass
  57.      *            任务
  58.      * @param time
  59.      *            时间设置,参考quartz说明文档
  60.      * @throws SchedulerException
  61.      * @throws ParseException
  62.      */
  63.     public static void addJob(String jobName, String jobGroupName,
  64.             String triggerName, String triggerGroupName, String jobClass, String time){
  65.         try {
  66.             Scheduler sched = gSchedulerFactory.getScheduler();
  67.             JobDetail jobDetail = new JobDetail(jobName, jobGroupName, Class.forName(jobClass));// 任务名,任务组,任务执行类
  68.             // 触发器
  69.             CronTrigger trigger = new CronTrigger(triggerName, triggerGroupName);// 触发器名,触发器组
  70.             trigger.setCronExpression(time);// 触发器时间设定
  71.             sched.scheduleJob(jobDetail, trigger);
  72.         } catch (Exception e) {
  73.             e.printStackTrace();
  74.             throw new RuntimeException(e);
  75.         }
  76.     }
  77.     /**
  78.      * 修改一个任务的触发时间(使用默认的任务组名,触发器名,触发器组名)
  79.      *
  80.      * @param jobName
  81.      * @param time
  82.      */
  83.     public static void modifyJobTime(String jobName, String time) {
  84.         try {
  85.             Scheduler sched = gSchedulerFactory.getScheduler();
  86.             CronTrigger trigger = (CronTrigger) sched.getTrigger(jobName, TRIGGER_GROUP_NAME);
  87.             if(trigger == null) {
  88.                 return;
  89.             }
  90.             String oldTime = trigger.getCronExpression();
  91.             if (!oldTime.equalsIgnoreCase(time)) {
  92.                 JobDetail jobDetail = sched.getJobDetail(jobName, JOB_GROUP_NAME);
  93.                 Class objJobClass = jobDetail.getJobClass();
  94.                 String jobClass = objJobClass.getName();
  95.                 removeJob(jobName);
  96.                 addJob(jobName, jobClass, time);
  97.             }
  98.         } catch (Exception e) {
  99.             e.printStackTrace();
  100.             throw new RuntimeException(e);
  101.         }
  102.     }
  103.     /**
  104.      * 修改一个任务的触发时间
  105.      *
  106.      * @param triggerName
  107.      * @param triggerGroupName
  108.      * @param time
  109.      */
  110.     public static void modifyJobTime(String triggerName,
  111.             String triggerGroupName, String time) {
  112.         try {
  113.             Scheduler sched = gSchedulerFactory.getScheduler();
  114.             CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerName, triggerGroupName);
  115.             if(trigger == null) {
  116.                 return;
  117.             }
  118.             String oldTime = trigger.getCronExpression();
  119.             if (!oldTime.equalsIgnoreCase(time)) {
  120.                 CronTrigger ct = (CronTrigger) trigger;
  121.                 // 修改时间
  122.                 ct.setCronExpression(time);
  123.                 // 重启触发器
  124.                 sched.resumeTrigger(triggerName, triggerGroupName);
  125.             }
  126.         } catch (Exception e) {
  127.             e.printStackTrace();
  128.             throw new RuntimeException(e);
  129.         }
  130.     }
  131.     /**
  132.      * 移除一个任务(使用默认的任务组名,触发器名,触发器组名)
  133.      *
  134.      * @param jobName
  135.      */
  136.     public static void removeJob(String jobName) {
  137.         try {
  138.             Scheduler sched = gSchedulerFactory.getScheduler();
  139.             sched.pauseTrigger(jobName, TRIGGER_GROUP_NAME);// 停止触发器
  140.             sched.unscheduleJob(jobName, TRIGGER_GROUP_NAME);// 移除触发器
  141.             sched.deleteJob(jobName, JOB_GROUP_NAME);// 删除任务
  142.         } catch (Exception e) {
  143.             e.printStackTrace();
  144.             throw new RuntimeException(e);
  145.         }
  146.     }
  147.     /**
  148.      * 移除一个任务
  149.      *
  150.      * @param jobName
  151.      * @param jobGroupName
  152.      * @param triggerName
  153.      * @param triggerGroupName
  154.      */
  155.     public static void removeJob(String jobName, String jobGroupName,
  156.             String triggerName, String triggerGroupName) {
  157.         try {
  158.             Scheduler sched = gSchedulerFactory.getScheduler();
  159.             sched.pauseTrigger(triggerName, triggerGroupName);// 停止触发器
  160.             sched.unscheduleJob(triggerName, triggerGroupName);// 移除触发器
  161.             sched.deleteJob(jobName, jobGroupName);// 删除任务
  162.         } catch (Exception e) {
  163.             e.printStackTrace();
  164.             throw new RuntimeException(e);
  165.         }
  166.     }
  167.     /**
  168.      * 启动所有定时任务
  169.      */
  170.     public static void startJobs() {
  171.         try {
  172.             Scheduler sched = gSchedulerFactory.getScheduler();
  173.             sched.start();
  174.         } catch (Exception e) {
  175.             e.printStackTrace();
  176.             throw new RuntimeException(e);
  177.         }
  178.     }
  179.     /**
  180.      * 关闭所有定时任务
  181.      */
  182.     public static void shutdownJobs() {
  183.         try {
  184.             Scheduler sched = gSchedulerFactory.getScheduler();
  185.             if(!sched.isShutdown()) {
  186.                 sched.shutdown();
  187.             }
  188.         } catch (Exception e) {
  189.             e.printStackTrace();
  190.             throw new RuntimeException(e);
  191.         }
  192.     }
  193. }

简单实现Schedule的Quartz的例子

 

第一步:引包

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

1、log4j-1.2.16

2、quartz-2.1.7

3、slf4j-api-1.6.1.jar

4、slf4j-log4j12-1.6.1.jar

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

第二步:创建要被定执行的任务类

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

[java]

  1. import java.text.SimpleDateFormat;
  2. import java.util.Date;
  3. import org.quartz.Job;
  4. import org.quartz.JobExecutionContext;
  5. import org.quartz.JobExecutionException;
  6. public class myJob implements Job {
  7.     @Override
  8.     public void execute(JobExecutionContext arg0) throws JobExecutionException {
  9.         SimpleDateFormat sdf = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss SSS”);
  10.         System.out.println(sdf.format(new Date()));
  11.     }
  12. }

第三步:创建任务调度,并执行

 

[java]

  1. import java.text.SimpleDateFormat;
  2. import java.util.Date;
  3. import org.quartz.CronTrigger;
  4. import org.quartz.JobDetail;
  5. import org.quartz.Scheduler;
  6. import org.quartz.SchedulerFactory;
  7. import org.quartz.impl.StdSchedulerFactory;
  8. public class Test {
  9.     public void go() throws Exception {
  10.         // 首先,必需要取得一个Scheduler的引用
  11.         SchedulerFactory sf = new StdSchedulerFactory();
  12.         Scheduler sched = sf.getScheduler();
  13.         String time=”0 51 11 ? * *”;
  14.         // jobs可以在scheduled的sched.start()方法前被调用
  15.         // job 1将每隔20秒执行一次
  16.         JobDetail job = new JobDetail(“job1”, “group1”, myJob.class);
  17.         CronTrigger trigger = new CronTrigger(“trigger1”, “group1”);
  18.         trigger.setCronExpression(time);
  19.         Date ft = sched.scheduleJob(job, trigger);
  20.         SimpleDateFormat sdf = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss SSS”);
  21.         System.out.println(
  22.                 job.getKey() + ” 已被安排执行于: ” + sdf.format(ft) + “,并且以如下重复规则重复执行: ” + trigger.getCronExpression());
  23.         // job 2将每2分钟执行一次(在该分钟的第15秒)
  24.         job = new JobDetail(“job2”, “group1”,myJob.class);
  25.         trigger = new CronTrigger(“trigger2”, “group1”);
  26.         trigger.setCronExpression(time);
  27.         ft = sched.scheduleJob(job, trigger);
  28.         System.out.println(
  29.                 job.getKey() + ” 已被安排执行于: ” + sdf.format(ft) + “,并且以如下重复规则重复执行: ” + trigger.getCronExpression());
  30.         // 开始执行,start()方法被调用后,计时器就开始工作,计时调度中允许放入N个Job
  31.         sched.start();
  32.         try {
  33.             // 主线程等待一分钟
  34.             Thread.sleep(60L * 1000L);
  35.         } catch (Exception e) {
  36.         }
  37.         // 关闭定时调度,定时器不再工作
  38.         sched.shutdown(true);
  39.     }
  40.     public static void main(String[] args) throws Exception {
  41.         Test test = new Test();
  42.         test.go();
  43.     }
  44. }

本文链接:https://www.aiunk.com/323/

“今年夏,遇一人,甚喜之,我无能,未能留之。”

—— 佚名《网络》
本站内容来源于互联网,所有转载、引用的文章、图片、视频等素材均来自网络公开渠道。我们对所转载的内容的版权和合法性不做任何保证。如果原作者或版权方认为本站内容侵犯其合法权益,敬请原作者或版权方及时联系我们,我们将在第一时间进行核实和处理,必要时删除相关内容。 本站的所有内容仅供个人学习与研究之用,不得用于任何商业用途。如需使用本站内容进行商业用途,请与原作者或版权所有者联系获取授权。 如有任何疑问或建议,请联系我们。