首页 > 代码库 > Java任务调度

Java任务调度

1.Timer

package com.qhong;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Timer;import java.util.TimerTask;public class Main {    public static void main(String[] args) {        Timer timer = new Timer();        long delay1 = 1 * 1000;        long period1 = 1000;        // 从现在开始 1 秒钟之后,每隔 1 秒钟执行一次 job1        timer.schedule(new TimerTest("job1" +DateUtils.format(new Date(),"yyyy-MM-dd HH:mm:ss")), delay1, period1);        long delay2 = 2 * 1000;        long period2 = 2000;        // 从现在开始 2 秒钟之后,每隔 2 秒钟执行一次 job2        timer.schedule(new TimerTest("job2"), delay2, period2);    }}class TimerTest extends TimerTask {    private String jobName = "";    public TimerTest(String jobName) {        super();        this.jobName = jobName;    }    @Override    public void run() {        System.out.println("execute " + jobName);    }}class DateUtils {    /** 时间格式(yyyy-MM-dd) */    public final static String DATE_PATTERN = "yyyy-MM-dd";    /** 时间格式(yyyy-MM-dd HH:mm:ss) */    public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";    public static String format(Date date) {        return format(date, DATE_PATTERN);    }    public static String format(Date date, String pattern) {        if(date != null){            SimpleDateFormat df = new SimpleDateFormat(pattern);            return df.format(date);        }        return null;    }}
execute job12017-03-10 19:48:45execute job2execute job12017-03-10 19:48:45execute job12017-03-10 19:48:45execute job2execute job12017-03-10 19:48:45execute job12017-03-10 19:48:45execute job2execute job12017-03-10 19:48:45execute job12017-03-10 19:48:45execute job2execute job12017-03-10 19:48:45execute job12017-03-10 19:48:45

Timer 的优点在于简单易用,但由于所有任务都是由同一个线程来调度,因此所有任务都是串行执行的,同一时间只能有一个任务在执行,前一个任务的延迟或异常都将会影响到之后的任务。

ScheduledExecutor

package com.qhong;import java.util.Date;import java.text.SimpleDateFormat;import java.util.concurrent.Executors;import java.util.concurrent.ScheduledExecutorService;import java.util.concurrent.TimeUnit;public class Main {    public static void main(String[] args) {        ScheduledExecutorService service = Executors.newScheduledThreadPool(10);        long initialDelay1 = 1;        long period1 = 1;        // 从现在开始1秒钟之后,每隔1秒钟执行一次job1        service.scheduleAtFixedRate(                new ScheduledExecutorTest("job1"), initialDelay1,                period1, TimeUnit.SECONDS);        long initialDelay2 = 2;        long delay2 = 2;        // 从现在开始2秒钟之后,每隔2秒钟执行一次job2        service.scheduleWithFixedDelay(                new ScheduledExecutorTest("job2"), initialDelay2,                delay2, TimeUnit.SECONDS);    }}class ScheduledExecutorTest implements Runnable {    private String jobName = "";    public ScheduledExecutorTest(String jobName) {        super();        this.jobName = jobName;    }    @Override    public void run() {        System.out.println("execute "+ DateUtils.format(new Date(),"yyyy-MM-dd HH:mm:ss") + jobName);    }}class DateUtils {    /** 时间格式(yyyy-MM-dd) */    public final static String DATE_PATTERN = "yyyy-MM-dd";    /** 时间格式(yyyy-MM-dd HH:mm:ss) */    public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";    public static String format(Date date) {        return format(date, DATE_PATTERN);    }    public static String format(Date date, String pattern) {        if(date != null){            SimpleDateFormat df = new SimpleDateFormat(pattern);            return df.format(date);        }        return null;    }}
execute 2017-03-10 20:03:53job1execute 2017-03-10 20:03:54job2execute 2017-03-10 20:03:54job1execute 2017-03-10 20:03:55job1execute 2017-03-10 20:03:56job1execute 2017-03-10 20:03:56job2execute 2017-03-10 20:03:57job1execute 2017-03-10 20:03:58job1execute 2017-03-10 20:03:58job2execute 2017-03-10 20:03:59job1execute 2017-03-10 20:04:00job1execute 2017-03-10 20:04:00job2execute 2017-03-10 20:04:01job1execute 2017-03-10 20:04:02job1execute 2017-03-10 20:04:02job2

展示了 ScheduledExecutorService 中两种最常用的调度方法 ScheduleAtFixedRate 和 ScheduleWithFixedDelay。

ScheduleAtFixedRate 每次执行时间为上一次任务开始起向后推一个时间间隔,即每次执行时间为 :initialDelay, initialDelay+period, initialDelay+2*period, …;

ScheduleWithFixedDelay 每次执行时间为上一次任务结束起向后推一个时间间隔,即每次执行时间为:initialDelay, initialDelay+executeTime+delay, initialDelay+2*executeTime+2*delay。

由此可见,ScheduleAtFixedRate 是基于固定时间间隔进行任务调度,ScheduleWithFixedDelay 取决于每次任务执行的时间长短,是基于不固定时间间隔进行任务调度。

 

https://www.ibm.com/developerworks/cn/java/j-lo-taskschedule/

Java任务调度