您的位置:首页 > 其它

可激活的间隔任务执行器

2013-08-07 10:27 92 查看
近来做项目,遇到一个很蛋疼的问题。以前早就遇到过,但是由于以前系统有变通的方法解决,也就没再弄这个事情。

什么问题呢 ? 就是一般情况下,系统会执行以下有时间间隔的周期性任务(比如,每小时执行一次垃圾数据的清理工作),但是,遇到特殊情况还要临时激活任务,让任务临时执行一下(比如突发性垃圾数据猛增)。

对于带有时间间隔的周期性任务,写个执行器应该是一件很容易的事情。开启一个线程,每次执行完任务就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;
}
}


这个就是执行器类了。当然,这个代码的质量不算高,因为,一个线程只能执行一个任务;线程的大部分时间都是在等待周期的到来。

但是,功能还是实现了。某些特定场景还是必须要用到的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: