任务调度中心 (普通版)【原】
2016-07-07 14:44
274 查看
任务调度中心
主要依赖quartz.jar相关类 判断cron表达式 , 在下次即将执行的时间在指定时间内时, 从线程池中取线程进行调度 (普通版)相关类
MyTrigger.java (主入口)MyJob.java
MyCallable.java
详细说明已都在java代码中体现.
相关jar包
quartz-2.2.3.zipMyTrigger.java (主函数入口)
package com.isoftstone.pcis.isc.job.king; import java.text.SimpleDateFormat; import java.util.UUID; import java.util.concurrent.Callable; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import org.quartz.CronScheduleBuilder; import org.quartz.JobBuilder; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.Trigger; import org.quartz.TriggerBuilder; import org.quartz.impl.StdSchedulerFactory; /** * 触发器小例子. * 1. 模拟从数据库中取完整信息,得到cron表达式 * 2. 判断时间是否在inSeconds(10)秒以内需要执行该任务 * 3. 如果在inSeconds(10)秒以内,从线程池中启动新线程,发送数据 * @author King * @time 2016/07/07 */ public class MyTrigger { //指定任务处于inSeconds秒内时,就开启新线程任务 private static final int inSeconds = 10;//秒 //时间格式化器 private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS"); //线程池 private static final ScheduledExecutorService executor = Executors.newScheduledThreadPool(2); public static void main(String[] args) throws Exception { // 模拟从数据库中取到一个与计划相关完整单行信息 Object dataFromDb = new Object(); // 模拟dataFromDb该行信息中cron表达式如下 String cronArg = "50 45 14 * * ?"; // 得到计划scheduler Scheduler scheduler = new StdSchedulerFactory().getScheduler(); // 创建工作任务job JobDetail job = JobBuilder.newJob().ofType(MyJob.class) .withIdentity("job1", "group1").build(); // 创建触发器trigger // 如果cronArg表达式不正确,会报java.text.ParseException,可以用来判断前台页面插入的cron表达式是否合法 Trigger trigger = TriggerBuilder.newTrigger() .withIdentity("trigger1", "group1").startNow() // .withSchedule(SimpleScheduleBuilder.repeatSecondlyForTotalCount(10,2)) .withSchedule(CronScheduleBuilder.cronSchedule(cronArg)) // .withSchedule(CalendarIntervalScheduleBuilder.calendarIntervalSchedule().withIntervalInHours(2)) .build(); // 对该计划指定运行 的工作任务和触发器,该行一定要有,不然触发器的下次执行时间会为null scheduler.scheduleJob(job, trigger); // 开始计划的执行,但这里最终目的只需要得到下次执行时间,而不需要真正执行,不然会启动线程增加性能消耗 //s.start(); //判断触发器trigger的下次执行时间是否临近 boolean flag = nearToRun(trigger); //如果临近,那么开启新线程 if(flag){ startNewThread(trigger,dataFromDb); } // 关闭计划scheduler // s.shutdown(true); } /** * 判断触发器trigger的下次执行时间是否临近inSeconds秒以内(目前为10秒以内) * @param trigger * @return */ public static boolean nearToRun(Trigger trigger){ // 打印下次执行时间,得到结果 System.out.println("trigger下次触发时间:" + sdf.format(trigger.getNextFireTime())); // 获取时差 = 该任务下次执行时间 - 当前时间 long delayTimeMillis = trigger.getNextFireTime().getTime() - System.currentTimeMillis(); // 如果 0秒<时差<10秒 ,那么启动线程(这个10秒到时由properties.参数决定) if (delayTimeMillis > 0 && delayTimeMillis < inSeconds * 1000) { return true; }else{ return false; } } /** * 从线程池开启新线程 * @param trigger 触发器 * @param dataFromDb 从数据库中取到的单行完整信息 * @throws Exception */ public static void startNewThread(Trigger trigger,Object dataFromDb) throws Exception{ //模拟从数据库中取到的数据dataInDb UUID uuid = UUID.randomUUID(); Callable<String> call = new MyCallableImpl(uuid.toString(),dataFromDb); // 再次获取时差,因为离executor.schedule(arg...)越近,越精确 long delayTimeMillis2 = trigger.getNextFireTime().getTime() - System.currentTimeMillis(); Future future = executor.schedule(call, delayTimeMillis2,TimeUnit.MILLISECONDS); //如果1 * 3600 * 1000 = 1小时内还得不到返回信息就会报java.util.concurrent.TimeoutException,该参数从dataFromDb中提取 String result = (String) future.get( 1 * 3600 * 1000,TimeUnit.MILLISECONDS); System.out.println("刚才启动的线程结束了,返回信息为:" + result); } }
MyJob.java
为了触发器而创建的类,实际情况并不会运行,但仍旧依赖该job,只要有一个空实现即可.package com.isoftstone.pcis.isc.job.king; import java.text.SimpleDateFormat; import java.util.Date; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; /** * Job实现类 * @author King * @time 2016/07/07 */ public class MyJob implements Job { @Override public void execute(JobExecutionContext arg0) throws JobExecutionException { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS"); System.out.println(sdf.format(new Date())+"I'm runing"); try { Thread.currentThread().sleep(1*1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(sdf.format(new Date())+"I'm runing"); } }
MyCallable
相当于线程的Runnable,实现类似于run()的call()方法,对真实业务进行调用package com.isoftstone.pcis.isc.job.king; import java.util.concurrent.Callable; /** * Callable实现类 * @author King * @time 2016/07/07 */ class MyCallable implements Callable<String> { private Object dataFromDb; public String name; public MyCallable() { super(); } public MyCallable(String name, Object dataFromDb) { this.name = name; this.dataFromDb = dataFromDb; } @Override public String call() throws Exception { System.out.println("CallableImpl:" + name + " is start"); // 把dataFromDb数据发送给指定URL,dataFromDb本身包含了URL地址,及超时时间等重要信息 // send(dataFromDb)/自定义一个方法用于发送 // 模拟发送情况,睡一会 Thread.sleep(3 * 1000); System.out.println("CallableImpl:" + name + "is end"); // 返回相关信息 return "success"; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Object getDataFromDb() { return dataFromDb; } public void setDataFromDb(Object dataFromDb) { this.dataFromDb = dataFromDb; } }
其它无关tips
得到一些job和trigger的状态JobDetail jobDetail = scheduler.getJobDetail(new JobKey("job1","group1")); System.out.println("jobDetail:\t"+jobDetail); TriggerState triggerState = scheduler.getTriggerState(new TriggerKey("trigger1","group1")); System.out.println("triggerState:\t"+triggerState);
View Code
相关文章推荐
- C++读取文件夹下的多个文件
- Hibernate官网jar包下载
- 分分钟解决iOS开发中App启动广告的功能
- 设置启动界面ios 8设置状态栏字体颜色
- Pos终端中的主密钥、工作密钥、pin密钥、mac密钥
- 编辑器
- ios 常用字符串的操作
- Extjs 回车查询
- Yii2框架与MongoDB拓展、Redis拓展的安装流程
- Android Files的文件读取解析+代码案例
- SIFT(scale invariant feature transform): 尺度不变特征变换
- MySql递归查询和Oracle递归查询
- MySql递归查询和Oracle递归查询
- 找资料
- java多线程的创建
- "/usr/local/openresty/nginx/html/index.html" is forbidden (13: Permission denied), client: 10.0.4.118, server: localhost, request: "GET / HTTP/1.1"
- Missing Ranges
- Android之ImageSwitcher
- ios制作一个速度表盘
- 从MySQL Bug#67718浅谈B+树索引的分裂优化