java任务调度管理_Java任务调度

java任务调度管理_Java任务调度
四种任务调度的 Java 实现:Timer
ScheduledExecutor
开源⼯具包 Quartz
开源⼯具包 JCronTab
Timer
相信⼤家都已经⾮常熟悉 java.util.Timer 了,它是最简单的⼀种实现任务调度的⽅法,下⾯给出⼀个具体的例⼦:清单 1. 使⽤ Timer 进⾏任务调度
package com.ibm.scheduler;
import java.util.Timer;
import java.util.TimerTask;
public class TimerTest extends TimerTask {
private String jobName = "";
public TimerTest(String jobName) {
super();
this.jobName = jobName;
}
@Override
public void run() {
海空在召唤
System.out.println("execute " + jobName);
}
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"), delay1, period1);
long delay2 = 2 * 1000;
long period2 = 2000;
// 从现在开始 2 秒钟之后,每隔 2 秒钟执⾏⼀次 job2
timer.schedule(new TimerTest("job2"), delay2, period2);
}
}
Output:
execute job1
execute job1
execute job2
execute job1
execute job1
execute job2
使⽤ Timer 实现任务调度的核⼼类是 Timer 和 TimerTask。其中 Timer 负责设定 TimerTask 的起始与间隔执⾏时间。使⽤者只需要创建⼀个 TimerTask 的继承类,实现⾃⼰的 run ⽅法,然后将其丢给 Timer 去执⾏即可。
Timer 的设计核⼼是⼀个 TaskList 和⼀个 TaskThread。Timer 将接收到的任务丢到⾃⼰的 TaskList 中,TaskList 按照 Task 的最初执⾏时间进⾏排序。TimerThread 在创建 Timer 时会启动成为⼀个守护线程。这个线程会轮询所有任务,到⼀个最近要执⾏的任务,然后休眠,当到达最近要执⾏任务的开始时间点,TimerThread 被唤醒并执⾏该任务。之后 TimerThread 更新最近⼀个要执⾏的任务,继续休眠。
Timer 的优点在于简单易⽤,但由于所有任务都是由同⼀个线程来调度,因此所有任务都是串⾏执⾏的,同⼀时间只能有⼀个任务在执⾏,前⼀个任务的延迟或异常都将会影响到之后的任务。
ScheduledExecutor
鉴于 Timer 的上述缺陷,Java 5 推出了基于线程池设计的 ScheduledExecutor。其设计思想是,每⼀个被调度的任务都会由线程池中⼀个线程去执⾏,因此任务是并发执⾏的,相互之间不会受到⼲扰。需要注意的是,只有当任务的执⾏时间到来时,ScheduedExecutor 才会真正启动⼀个线程,其余时间 ScheduledExecutor 都是在轮询任务的状态。
清单 2. 使⽤ ScheduledExecutor 进⾏任务调度
package com.ibm.scheduler;
import urrent.Executors;
import urrent.ScheduledExecutorService;
import urrent.TimeUnit;
public class ScheduledExecutorTest implements Runnable {
private String jobName = "";
public ScheduledExecutorTest(String jobName) {
super();
this.jobName = jobName;
}
@Override
public void run() {
System.out.println("execute " + jobName);
}
public static void main(String[] args) {
ScheduledExecutorService service = wScheduledThreadPool(10);
long initialDelay1 = 1;
long period1 = 1;
// 从现在开始1秒钟之后,每隔1秒钟执⾏⼀次job1
service.scheduleAtFixedRate(
new ScheduledExecutorTest("job1"), initialDelay1,
period1, TimeUnit.SECONDS);
long initialDelay2 = 1;
long delay2 = 1;
// 从现在开始2秒钟之后,每隔2秒钟执⾏⼀次job2
service.scheduleWithFixedDelay(
new ScheduledExecutorTest("job2"), initialDelay2,
delay2, TimeUnit.SECONDS);
}
}
电子式电压互感器
Output:
execute job1
execute job1
execute job2
execute job1
execute job1
execute job2
清单 2 展⽰了 ScheduledExecutorService 中两种最常⽤的调度⽅法 ScheduleAtFixedRate 和 Sched
uleWithFixedDelay。ScheduleAtFixedRate 每次执⾏时间为上⼀次任务开始起向后推⼀个时间间隔,即每次执⾏时间为 :initialDelay, initialDelay+period, initialDelay+2*period, …;ScheduleWithFixedDelay 每次执⾏时间为上⼀次任务结束起向后推⼀个时间间隔,即每次执⾏时间为:initialDelay, initialDelay+executeTime+delay, initialDelay+2*executeTime+2*delay。由此可见,ScheduleAtFixedRate 是基于固定时间间隔进⾏任务调度,ScheduleWithFixedDelay 取决于每次任务执⾏的时间长短,是基于不固定时间间隔进⾏任务调度。
⽤ ScheduledExecutor 和 Calendar 实现复杂任务调度
川草乌
Timer 和 ScheduledExecutor 都仅能提供基于开始时间与重复间隔的任务调度,不能胜任更加复杂的调度需求。⽐如,设置每星期⼆的16:38:10 执⾏任务。该功能使⽤ Timer 和 ScheduledExecutor 都不能直接实现,但我们可以借助 Calendar 间接实现该功能。
清单 3. 使⽤ ScheduledExcetuor 和 Calendar 进⾏任务调度
package com.ibm.scheduler;
import java.util.Calendar;
import java.util.Date;
import java.util.TimerTask;
import urrent.Executors;
import urrent.ScheduledExecutorService;
import urrent.TimeUnit;
public class ScheduledExceutorTest2 extends TimerTask {
private String jobName = "";
public ScheduledExceutorTest2(String jobName) {
super();
this.jobName = jobName;
}
静水压力
@Override
dmso
public void run() {
System.out.println("Date = "+new Date()+", execute " + jobName);
}
/**
* 计算从当前时间currentDate开始,满⾜条件dayOfWeek, hourOfDay,
* minuteOfHour, secondOfMinite的最近时间
* @return
*/
public Calendar getEarliestDate(Calendar currentDate, int dayOfWeek,
跨界也疯狂int hourOfDay, int minuteOfHour, int secondOfMinite) {
//计算当前时间的WEEK_OF_YEAR,DAY_OF_WEEK, HOUR_OF_DAY, MINUTE,SECOND等各个字段值int currentWeekOfYear = (Calendar.WEEK_OF_YEAR);
int currentDayOfWeek = (Calendar.DAY_OF_WEEK);
int currentHour = (Calendar.HOUR_OF_DAY);
int currentMinute = (Calendar.MINUTE);
int currentSecond = (Calendar.SECOND);
//如果输⼊条件中的dayOfWeek⼩于当前⽇期的dayOfWeek,则WEEK_OF_YEAR需要推迟⼀周
boolean weekLater = false;
if (dayOfWeek < currentDayOfWeek) {
weekLater = true;
} else if (dayOfWeek == currentDayOfWeek) {
//当输⼊条件与当前⽇期的dayOfWeek相等时,如果输⼊条件中的
//hourOfDay⼩于当前⽇期的
/
/currentHour,则WEEK_OF_YEAR需要推迟⼀周
if (hourOfDay < currentHour) {
weekLater = true;
} else if (hourOfDay == currentHour) {
//当输⼊条件与当前⽇期的dayOfWeek, hourOfDay相等时,
//如果输⼊条件中的minuteOfHour⼩于当前⽇期的
//currentMinute,则WEEK_OF_YEAR需要推迟⼀周
if (minuteOfHour < currentMinute) {
weekLater = true;
} else if (minuteOfHour == currentSecond) {
//当输⼊条件与当前⽇期的dayOfWeek, hourOfDay,
/
/minuteOfHour相等时,如果输⼊条件中的
//secondOfMinite⼩于当前⽇期的currentSecond,
//则WEEK_OF_YEAR需要推迟⼀周
if (secondOfMinite < currentSecond) {
weekLater = true;
}
}
}
}
if (weekLater) {
//设置当前⽇期中的WEEK_OF_YEAR为当前周推迟⼀周
currentDate.set(Calendar.WEEK_OF_YEAR, currentWeekOfYear + 1);
}
// 设置当前⽇期中的DAY_OF_WEEK,HOUR_OF_DAY,MINUTE,SECOND为输⼊条件中的值。currentDate.set(Calendar.DAY_OF_WEEK, dayOfWeek);
currentDate.set(Calendar.HOUR_OF_DAY, hourOfDay);
currentDate.set(Calendar.MINUTE, minuteOfHour);
currentDate.set(Calendar.SECOND, secondOfMinite);
return currentDate;
}
public static void main(String[] args) throws Exception {
ScheduledExceutorTest2 test = new ScheduledExceutorTest2("job1");
//获取当前时间
Calendar currentDate = Instance();
long currentDateLong = Time().getTime();
System.out.println("Current Date = " + Time().toString());
//计算满⾜条件的最近⼀次执⾏时间
Calendar earliestDate = test

本文发布于:2024-09-21 19:46:21,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/284537.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:任务   时间   线程   任务调度   需要   开始
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议