「调度java」调度中心控制台

博主:adminadmin 2022-12-01 18:18:06 57

本篇文章给大家谈谈调度java,以及调度中心控制台对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

线程的调度分为几种模型,在java中是使用哪种调度模型

Java程序属于抢占式调度,哪个线程的优先级高,哪个线程抢到的CPU时间片的概率就高;如果两个线程同一个优先级,则CPU随机选择一个执行。

azkaban在调度java程序时要如何传递参数?

azkaban的工作流中的参数可以分为如下几个类型:azkaban UI 页面输入参数, 环境变量参数, job作业文件中定义的参数,工作流的用户定义的属性文件,上游作业传递给下游的参数,工作流运行时产生的系统参数,job的common参数等. 参数的作业范围分类,对当前job有效局部有效,对整个工作流全局有效. 1. Job配置中的参数全局参数,在整个工作流的作业文件配置中,都可以通过 ${参数名} 的方式引用使用. common参数配置 除了type,command,decpenden

为什么使用java 任务调度系统

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 java.util.concurrent.Executors;

import java.util.concurrent.ScheduledExecutorService;

import java.util.concurrent.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 = Executors.newScheduledThreadPool(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 和 ScheduleWithFixedDelay。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 java.util.concurrent.Executors;

import java.util.concurrent.ScheduledExecutorService;

import java.util.concurrent.TimeUnit;

public class ScheduledExceutorTest2 extends TimerTask {

private String jobName = "";

public ScheduledExceutorTest2(String jobName) {

super();

this.jobName = jobName;

}

@Override

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 = currentDate.get(Calendar.WEEK_OF_YEAR);

int currentDayOfWeek = currentDate.get(Calendar.DAY_OF_WEEK);

int currentHour = currentDate.get(Calendar.HOUR_OF_DAY);

int currentMinute = currentDate.get(Calendar.MINUTE);

int currentSecond = currentDate.get(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 = Calendar.getInstance();

long currentDateLong = currentDate.getTime().getTime();

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

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

Calendar earliestDate = test

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

long earliestDateLong = earliestDate.getTime().getTime();

System.out.println("Earliest Date = "

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

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

long delay = earliestDateLong - currentDateLong;

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

long period = 7 * 24 * 60 * 60 * 1000;

ScheduledExecutorService service = Executors.newScheduledThreadPool(10);

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

service.scheduleAtFixedRate(test, delay, period,

TimeUnit.MILLISECONDS);

}

}

Output:

Current Date = Wed Feb 02 17:32:01 CST 2011

Earliest Date = Tue Feb 8 16:38:10 CST 2011

Date = Tue Feb 8 16:38:10 CST 2011, execute job1

Date = Tue Feb 15 16:38:10 CST 2011, execute job1

如何编写一个定时调度java程序

目前有两种流行Spring定时器配置:Java的Timer类和OpenSymphony的Quartz。

1.Java Timer定时

首先继承java.util.TimerTask类实现run方法

import java.util.TimerTask;

public class EmailReportTask extends TimerTask{

@Override

public void run() {

...

}

}

在Spring定义

...

配置Spring定时器

bean id="scheduleReportTask" class="org.springframework.scheduling.timer.ScheduledTimerTask"

property name="timerTask" ref="reportTimerTask" /

property name="period"

value86400000value

property

bean

timerTask属性告诉ScheduledTimerTask运行哪个。86400000代表24个小时

启动Spring定时器

Spring的TimerFactoryBean负责启动定时任务

bean class="org.springframework.scheduling.timer.TimerFactoryBean"

property name="scheduledTimerTasks"

listref bean="scheduleReportTask"/list

property

bean

scheduledTimerTasks里显示一个需要启动的定时器任务的列表。

可以通过设置delay属性延迟启动

bean id="scheduleReportTask" class="org.springframework.scheduling.timer.ScheduledTimerTask"

property name="timerTask" ref="reportTimerTask" /

property name="period"

value86400000value

property

property name="delay"

value3600000value

property

bean

这个任务我们只能规定每隔24小时运行一次,无法精确到某时启动

2.Quartz定时器

首先继承QuartzJobBean类实现executeInternal方法

import org.quartz.JobExecutionContext;

import org.quartz.JobExecutionException;

import org.springframework.scheduling.quartz.QuartzJobBean;

public class EmailReportJob extends QuartzJobBean{

protected void executeInternal(JobExecutionContext arg0)

throws JobExecutionException {

...

}

}

在Spring中定义

bean id="reportJob" class="org.springframework.scheduling.quartz.JobDetailBean"

property name="jobClass"

valueEmailReportJobvalue

property

property name="jobDataAsMap"

map

entry key="courseService"

ref bean="courseService"/

entry

map

property

bean

在这里我们并没有直接声明一个EmailReportJob Bean,而是声明了一个JobDetailBean。这个是Quartz的特点。JobDetailBean是Quartz的org.quartz.JobDetail的子类,它要求通过jobClass属性来设置一个Job对象。

使用Quartz的JobDetail中的另一个特别之处是EmailReportJob的courseService属性是间接设置的。JobDetail的jobDataAsMap属性接受一个Map,包括设置给jobClass的各种属性,当。JobDetailBean实例化时,它会将courseService Bean注入到EmailReportJob 的courseService 属性中。

启动定时器

Quartz的org.quartz.Trigger类描述了何时及以怎样的频度运行一个Quartz工作。Spring提供了两个触发器SimpleTriggerBean和CronTriggerBean。

SimpleTriggerBean与scheduledTimerTasks类似。指定工作的执行频度,模仿scheduledTimerTasks配置 .

bean id="simpleReportTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean"

property name="jobDetail" ref="reprotJob" /

property name="startDelay"

value360000value

property

property name="repeatInterval"

value86400000value

property

bean

startDelay也是延迟1个小时启动

CronTriggerBean指定工作的准确运行时间

bean id="cronReportTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"

property name="jobDetail" ref="reprotJob" /

property name="cronExpression"

value0 0 6 * * ?value

property

bean

属性cronExpression告诉何时触发。最神秘就是cron表达式:

Linux系统的计划任务通常有cron来承担。一个cron表达式有至少6个(也可能7个)有空格分隔的时间元素。从左到右:

1.秒2.分3.小时4.月份中的日期(1-31)5.月份(1-12或JAN-DEC)6.星期中的日期(1-7或SUN-SAT)7.年份(1970-2099)

每个元素都显示的规定一个值(如6),一个区间(9-12),一个列表(9,11,13)或一个通配符(*)。因为4和6这两个元素是互斥的,因此应该通过设置一个问号(?)来表明不想设置的那个字段,“/”如果值组合就表示重复次数(10/6表示每10秒重复6次)。

启动定时器

bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"

property name="triggers"

listref bean="cronReportTrigger"/list

property

bean

triggers属性接受一组触发器。

java怎么同步调度?

第一种方法: 将synchronized加在需要互斥的方法上。

每个锁对象(JLS中叫monitor)都有两个队列,一个是就绪队列,一个是阻塞队列,就绪队列存储了将要获得锁的线程,阻塞队列存储了被阻塞的线程,当一个线程被唤醒(notify)后,才会进入到就绪队列,等待CPU的调度,反之,当一个线程被wait后,就会进入阻塞队列,等待下一次被唤醒,这个涉及到线程间的通信,下一篇博文会说明。看我们的例子,当第一个线程执行输出方法时,获得同步锁,执行输出方法,恰好此时第二个线程也要执行输出方法,但发现同步锁没有被释放,第二个线程就会进入就绪队列,等待锁被释放。一个线程执行互斥代码过程如下:

1. 获得同步锁;

2. 清空工作内存;

3. 从主内存拷贝对象副本到工作内存;

4. 执行代码(计算或者输出等);

5. 刷新主内存数据;

6. 释放同步锁。

所以,synchronized既保证了多线程的并发有序性,又保证了多线程的内存可见性。

第二种方法: 共享变量前加volatile关键字

volatile是一种弱的同步手段,相对于synchronized来说,某些情况下使用,可能效率更高,因为它不是阻塞的,尤其是读操作时,加与不加貌似没有影响,处理写操作的时候,可能消耗的性能更多些。

volatile可以保证内存可见性,不能保证并发有序性

关于调度java和调度中心控制台的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

The End

发布于:2022-12-01,除非注明,否则均为首码项目网原创文章,转载请注明出处。