可激活的间隔任务执行器
2013-08-07 10:27
92 查看
近来做项目,遇到一个很蛋疼的问题。以前早就遇到过,但是由于以前系统有变通的方法解决,也就没再弄这个事情。
什么问题呢 ? 就是一般情况下,系统会执行以下有时间间隔的周期性任务(比如,每小时执行一次垃圾数据的清理工作),但是,遇到特殊情况还要临时激活任务,让任务临时执行一下(比如突发性垃圾数据猛增)。
对于带有时间间隔的周期性任务,写个执行器应该是一件很容易的事情。开启一个线程,每次执行完任务就sleep一个时间间隔,这样往复循环下去,就可以了。
基于上述思路,列举部分代码如下:
上述的是一个接口类,它有父接口,有execute方法,用于执行任务内容;有getDelay方法,用于获取执行任务的时间间隔。
这个就是执行器类了。当然,这个代码的质量不算高,因为,一个线程只能执行一个任务;线程的大部分时间都是在等待周期的到来。
但是,功能还是实现了。某些特定场景还是必须要用到的。
什么问题呢 ? 就是一般情况下,系统会执行以下有时间间隔的周期性任务(比如,每小时执行一次垃圾数据的清理工作),但是,遇到特殊情况还要临时激活任务,让任务临时执行一下(比如突发性垃圾数据猛增)。
对于带有时间间隔的周期性任务,写个执行器应该是一件很容易的事情。开启一个线程,每次执行完任务就sleep一个时间间隔,这样往复循环下去,就可以了。
基于上述思路,列举部分代码如下:
package houlei.support.util.task; /** * 间隔执行的周期任务 */ public interface DelayTask extends CycleTask{ /** * 调度任务的时间间隔 */ long getDelay(); }
上述的是一个接口类,它有父接口,有execute方法,用于执行任务内容;有getDelay方法,用于获取执行任务的时间间隔。
package houlei.support.util.task; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import houlei.support.lang.ErrorHandler; /** * 可激活的间隔任务执行器。只执行间隔执行的周期任务。 * <p>主要执行间隔任务,当任务处于休眠期时,可通过调用{@link #active()}方法,唤醒执行器,激活当前任务。</p> */ public class ActivableDelayTaskWorker { private static final Logger LOG = LoggerFactory.getLogger(ActivableDelayTaskWorker.class); private ErrorHandler errorHandler = new ErrorHandler() { public void doHandler(Throwable throwable, String s) { LOG.error(s, throwable); } }; private DelayTask delayTask; private Worker worker; private String name; private volatile boolean busy = false; /** * 执行器线程 */ private class Worker extends Thread{ public Worker() { super(name); } private volatile boolean running = false; public void run(){ LOG.info("线程["+Thread.currentThread().getName()+"]开始运行。"); while(running){ try { busy = true; delayTask.execute(); busy = false; try { synchronized (worker) { worker.wait(delayTask.getDelay()); } } catch (InterruptedException e) { } } catch (Throwable t) { errorHandler.doHandler(t, "任务["+name+"]在调用过程中出现异常。"); } } LOG.info("线程["+Thread.currentThread().getName()+"]运行结束。"); } } /** * @param name 线程名称 * @param delayTask 周期任务的实例 */ public ActivableDelayTaskWorker(String name, DelayTask delayTask) { if(name==null)throw new IllegalArgumentException("参数[name]不能为空"); if(delayTask==null)throw new IllegalArgumentException("参数[delayTask]不能为空"); this.name = name;this.delayTask = delayTask; worker = new Worker(); } /** * 唤醒执行器,激活当前任务。 */ public void active(){ if(busy)return; synchronized (worker) { worker.notify(); } } /** * 执行器的工作状况,是否处于任务调度阶段。 */ public boolean isBusy() { return busy; } /** * 开启调度线程 */ public void startup(){ if(!worker.running){ worker.running = true; worker.start(); } } /** * 结束调度线程 */ public void shutdown(){ if(worker.running){ worker.running = false; worker.interrupt(); try { worker.join(5000); } catch (InterruptedException e) { errorHandler.doHandler(e, "任务["+name+"]无法在5秒内终止"); } } } public void setErrorHandler(ErrorHandler errorHandler) { this.errorHandler = errorHandler; } public ErrorHandler getErrorHandler() { return errorHandler; } public DelayTask getDelayTask() { return delayTask; } public String getName() { return name; } }
这个就是执行器类了。当然,这个代码的质量不算高,因为,一个线程只能执行一个任务;线程的大部分时间都是在等待周期的到来。
但是,功能还是实现了。某些特定场景还是必须要用到的。
相关文章推荐
- EOS Platform7.5配置了固定时刻触发的定时任务,没有准确的按照配置的间隔时间触发
- 巧妙设置 激活Google日历任务功能-系统技巧
- ORACLE定时任务时间间隔设置
- 并发编程--在执行器中取消任务
- spring定时任务--多个任务和执行时间间隔配置
- Java并发编程高级篇(八):在执行器中取消任务
- 并发编程--在执行器中控制任务的完成
- Java并发编程高级篇(七):使用执行器周期性地执行任务
- Java7并发编程--4.2、在执行器中执行任务并且返回结果
- Java并发编程-21-在执行器中分离任务的启动与结果的处理
- 实现一个所有任务都是按各自自定义的时间间隔周期性执行的线程池
- php版本的cron定时任务执行器使用实例
- Linux中Cron任务间隔执行:每隔几分钟/几小时/几天
- Java并发编程高级篇(六):在执行器中延时执行任务
- java中计时器的用法Timer和TimerTask的用法__java中利用Timer与TImerTask 计时器间隔执行任务
- 本文实例讲述了php版本的cron定时任务执行器使用方法
- IOS线程数据篇8之GCD功能使用大全:队列阻塞挂起(一次激活所有阻塞任务)
- Linux中Cron任务间隔执行:每隔几分钟/几小时/几天
- Java7并发编程--4.4、在执行器中执行任务并且返回结果
- 学习《spring 3.x企业应用开发实战》之任务调度和异步执行器