任务调度.docx

上传人:b****4 文档编号:11931781 上传时间:2023-04-16 格式:DOCX 页数:19 大小:306.64KB
下载 相关 举报
任务调度.docx_第1页
第1页 / 共19页
任务调度.docx_第2页
第2页 / 共19页
任务调度.docx_第3页
第3页 / 共19页
任务调度.docx_第4页
第4页 / 共19页
任务调度.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

任务调度.docx

《任务调度.docx》由会员分享,可在线阅读,更多相关《任务调度.docx(19页珍藏版)》请在冰豆网上搜索。

任务调度.docx

任务调度

任务调度

从网上发现了好多任务调度的框架,对于小白的编辑来说也很困惑啊,那让我们一起慢慢走近任务调度框架吧!

什么是任务调度

任务调度是操作系统的重要组成部分,而对于实时操作系统,任务调度直接影响其实时性能。

任务调度方式常规可分为:

可打断调度(实时系统基本功能):

关键防止优先级倒置;

不可打断调度:

先来先服务,不可中断。

任务调度算法可分为:

事件驱动调度算法:

根据事件的先后以及任务的优先级安排任务的执行;

时钟驱动调度算法:

一般用于周期任务。

事件驱动调度,依赖外部硬件设备,通过产生中断方式为任务调度提供信号。

分两种:

集成事件驱动调度:

中断的优先级与任务的优先级相对应,中断只有在其优先级高于正在执行的任务时才会被处理器响应。

非集成事件驱动调度:

任务通过外部中断启动,中断优先级与相关任务优先级没有关系。

前言

任务调度是指基于给定时间点,给定时间间隔或者给定执行次数自动执行任务。

本文由浅入深介绍四种任务调度的Java实现:

∙Timer

∙ScheduledExecutor

∙开源工具包Quartz

∙开源工具包JCronTab

Timer

Timer:

是生产者--消费者模型的一种特例:

多生产者,单消费者模型。

优点:

简单易用

缺点:

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

Java代码测试timer:

Timer测试用例一:

packagecom.zx.scheduler;

importjava.util.Timer;

importjava.util.TimerTask;

publicclassTimerTestextendsTimerTask{

privateStringjobName="";

publicTimerTest(StringjobName){

super();

this.jobName=jobName;

}

@Override

publicvoidrun(){

System.out.println("execute"+jobName);

}

publicstaticvoidmain(String[]args){

Timertimer=newTimer();

longdelay1=1*1000;

longperiod1=1000;

//从现在开始1秒钟之后,每隔1秒钟执行一次job1

timer.schedule(newTimerTest("job1"),delay1,period1);

longdelay2=2*1000;

longperiod2=2000;

//从现在开始2秒钟之后,每隔2秒钟执行一次job2

timer.schedule(newTimerTest("job2"),delay2,period2);

}

}

/**

输出结果:

executejob1

executejob1

executejob2

executejob1

……

*/

Timer测试用例二:

packagecom.zx.scheduler;

importjava.util.Date;

importjava.util.Timer;

importjava.util.TimerTask;

publicclassPlainTimerTaskextendsTimerTask{

@Override

publicvoidrun(){

System.out.println("输出时间:

"+newDate());

}

publicstaticvoidmain(String[]args){

Timertimer=newTimer();

timer.schedule(newPlainTimerTask(),5000L);

}

}

/**

*输出时间:

MonFeb2911:

16:

49CST2016

*/

Timer测试用例三:

packagecom.zx.test;

importjava.util.Timer;

importjava.util.TimerTask;

publicclassTimerTestextendsTimerTask{

staticintflax=0;

@Override

publicvoidrun(){

System.out.println("test"+flax);

flax++;

}

publicstaticvoidmain(String[]args){

Timert=newTimer();

longdelay=1000;

longperiod=10*1000;

t.schedule(newTimerTest(),delay,period);//从现在开始1秒钟之后,每隔10秒钟执行一次

}

}

/**结果

test0

test1

test2

test3

*/

ScheduledExecutor

ScheduledExecutor:

其设计思想是,每一个被调度的任务都会由线程池中一个线程去执行,因此任务是并发执行的,相互之间不会受到干扰。

需要注意的是,只有当任务的执行时间到来时,ScheduedExecutor才会真正启动一个线程,其余时间ScheduledExecutor都是在轮询任务的状态。

Java代码测试ScheduledExecutor

packagecom.zx.scheduler;

importjava.util.concurrent.Executors;

importjava.util.concurrent.ScheduledExecutorService;

importjava.util.concurrent.TimeUnit;

publicclassScheduledExecutorTestimplementsRunnable{

privateStringjobName="";

publicScheduledExecutorTest(StringjobName){

super();

this.jobName=jobName;

}

@Override

publicvoidrun(){

System.out.println("execute"+jobName);

}

publicstaticvoidmain(String[]args){

ScheduledExecutorServiceservice=Executors.newScheduledThreadPool(10);

longinitialDelay1=1;

longperiod1=1;

//从现在开始1秒钟之后,每隔1秒钟执行一次job1

service.scheduleAtFixedRate(

newScheduledExecutorTest("job1"),initialDelay1,

period1,TimeUnit.SECONDS);

longinitialDelay2=1;

longdelay2=1;

//从现在开始2秒钟之后,每隔2秒钟执行一次job2

service.scheduleWithFixedDelay(

newScheduledExecutorTest("job2"),initialDelay2,

delay2,TimeUnit.SECONDS);

}

}

/**

结果:

executejob2

executejob1

executejob1

executejob2

executejob1

executejob2

*/

Calendar

实现复杂任务调度

Java代码测试Calendar

packagecom.zx.scheduler;

importjava.util.Calendar;

importjava.util.Date;

importjava.util.TimerTask;

importjava.util.concurrent.Executors;

importjava.util.concurrent.ScheduledExecutorService;

importjava.util.concurrent.TimeUnit;

publicclassScheduledExceutorTest2extendsTimerTask{

privateStringjobName="";

publicScheduledExceutorTest2(StringjobName){

super();

this.jobName=jobName;

}

@Override

publicvoidrun(){

System.out.println("Date="+newDate()+",execute"+jobName);

}

/**

*计算从当前时间currentDate开始,满足条件dayOfWeek,hourOfDay,

*minuteOfHour,secondOfMinite的最近时间

*@return

*/

publicCalendargetEarliestDate(CalendarcurrentDate,intdayOfWeek,

inthourOfDay,intminuteOfHour,intsecondOfMinite){

//计算当前时间的WEEK_OF_YEAR,DAY_OF_WEEK,HOUR_OF_DAY,MINUTE,SECOND等各个字段值

intcurrentWeekOfYear=currentDate.get(Calendar.WEEK_OF_YEAR);

intcurrentDayOfWeek=currentDate.get(Calendar.DAY_OF_WEEK);

intcurrentHour=currentDate.get(Calendar.HOUR_OF_DAY);

intcurrentMinute=currentDate.get(Calendar.MINUTE);

intcurrentSecond=currentDate.get(Calendar.SECOND);

//如果输入条件中的dayOfWeek小于当前日期的dayOfWeek,则WEEK_OF_YEAR需要推迟一周

booleanweekLater=false;

if(dayOfWeek

weekLater=true;

}elseif(dayOfWeek==currentDayOfWeek){

//当输入条件与当前日期的dayOfWeek相等时,如果输入条件中的

//hourOfDay小于当前日期的

//currentHour,则WEEK_OF_YEAR需要推迟一周

if(hourOfDay

weekLater=true;

}elseif(hourOfDay==currentHour){

//当输入条件与当前日期的dayOfWeek,hourOfDay相等时,

//如果输入条件中的minuteOfHour小于当前日期的

//currentMinute,则WEEK_OF_YEAR需要推迟一周

if(minuteOfHour

weekLater=true;

}elseif(minuteOfHour==currentSecond){

//当输入条件与当前日期的dayOfWeek,hourOfDay,

//minuteOfHour相等时,如果输入条件中的

//secondOfMinite小于当前日期的currentSecond,

//则WEEK_OF_YEAR需要推迟一周

if(secondOfMinite

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);

returncurrentDate;

}

publicstaticvoidmain(String[]args)throwsException{

ScheduledExceutorTest2test=newScheduledExceutorTest2("job1");

//获取当前时间

CalendarcurrentDate=Calendar.getInstance();

longcurrentDateLong=currentDate.getTime().getTime();

System.out.println("CurrentDate="+currentDate.getTime().toString());

//计算满足条件的最近一次执行时间

CalendarearliestDate=test

.getEarliestDate(currentDate,3,16,38,10);

longearliestDateLong=earliestDate.getTime().getTime();

System.out.println("EarliestDate="

+earliestDate.getTime().toString());

//计算从当前时间到最近一次执行时间的时间间隔

longdelay=earliestDateLong-currentDateLong;

//计算执行周期为一星期

longperiod=7*24*60*60*1000;

ScheduledExecutorServiceservice=Executors.newScheduledThreadPool(10);

//从现在开始delay毫秒之后,每隔一星期执行一次job1

service.scheduleAtFixedRate(test,delay,period,

TimeUnit.MILLISECONDS);

}

}

/**

输出结果:

CurrentDate=WedFeb0217:

32:

01CST2011

EarliestDate=TueFeb816:

38:

10CST2011

Date=TueFeb816:

38:

10CST2011,executejob1

Date=TueFeb1516:

38:

10CST2011,executejob1

*/

Quartz

Java代码测试quartz

packagecom.zx.scheduler;

importjava.util.Date;

importorg.quartz.Job;

importorg.quartz.JobDetail;

importorg.quartz.JobExecutionContext;

importorg.quartz.JobExecutionException;

importorg.quartz.Scheduler;

importorg.quartz.SchedulerFactory;

importorg.quartz.Trigger;

importorg.quartz.helpers.TriggerUtils;

publicclassQuartzTestimplementsJob{

@Override

//该方法实现需要执行的任务

publicvoidexecute(JobExecutionContextarg0)throwsJobExecutionException{

System.out.println("Generatingreport-"+arg0.getJobDetail().getFullName()+",type="+arg0.getJobDetail().getJobDataMap().get("type"));

System.out.println(newDate().toString());

}

publicstaticvoidmain(String[]args){

try{

//创建一个Scheduler

SchedulerFactoryschedFact=

neworg.quartz.impl.StdSchedulerFactory();

Schedulersched=schedFact.getScheduler();

sched.start();

//创建一个JobDetail,指明name,groupname,以及具体的Job类名,

//该Job负责定义需要执行任务

JobDetailjobDetail=newJobDetail("myJob","myJobGroup",QuartzTest.class);

jobDetail.getJobDataMap().put("type","FULL");

//创建一个每周触发的Trigger,指明星期几几点几分执行

Triggertrigger=TriggerUtils.makeWeeklyTrigger(2,17,47);//注意:

2,17,47表示的是周一17:

47执行任务

trigger.setGroup("myTriggerGroup");

//从当前时间的下一秒开始执行

trigger.setStartTime(TriggerUtils.getEvenSecondDate(newDate()));

//指明trigger的name

trigger.setName("myTrigger");

//用scheduler将JobDetail与Trigger关联在一起,开始调度任务

sched.scheduleJob(jobDetail,trigger);

}catch(Exceptione){

e.printStackTrace();

}

}

}

结果:

问题及方案:

使用Quartz时需要添加jar包,报此错误,缺少quartz-版本号.jar

例如:

quartz-1.5.2.jar

运行后:

报此错误:

缺少commons-logging.jar

Quartz整合spring

创建web工程:

itcast-quartz

Main类

packagecom.itcast.quartz;

importorg.springframework.context.support.ClassPathXmlApplicationContext;

publicclassMain{

publicstaticvoidmain(String[]args){

newClassPathXmlApplicationContext("classpath:

applicationContext-scheduler.xml");

}

}

MyJob类

packagecom.itcast.quartz;

importorg.quartz.JobExecutionContext;

importorg.quartz.JobExecutionException;

importorg.springframework.context.ApplicationContext;

importorg.springframework.scheduling.quartz.QuartzJobBean;

publicclassMyJobextendsQuartzJobBean{

@Override

protectedvoidexecuteInternal(JobExecutionContextcontext)

throwsJobExecutionException{

System.out.println("myJob执行了。

"+context.getTrigger().getKey().getName());

try{

ApplicationContextapplicationContext=(ApplicationContext)context.getJobDetail().getJobDataMap().get("applicationContext");

System.out.println("获取到的spring容器是"+applicationContext);

}catch(Exceptione){

System.out.println(e.getMessage());

e.printStackTrace();

System.out.println("出错了");

}

}

}

applicationContext-scheduler.xml

xmlversion="1.0"encoding="UTF-8"?

>

//www.springframework.org/schema/beans"

xmlns:

context="http:

//www.springframework.org/schema/context"

xmlns:

xsi="http:

//www.w3.org/2001/XMLSchema-instance"

x

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 财务管理

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1