java 计划任务

本文介绍了一个用于定期检查数据库表数据是否发生变化,并在有更新时执行特定任务的抽象基类。具体实现以检查Student表为例,展示了如何在检测到数据变化后更新数据库。

有一些程序是永不停歇的,比如监控某个数据表中的内容是否变化。若有变化通知给其他程序。下面两个类可以作为模版。

/**
 * 定期检查某个数据库中某表中的数据是否有变,若有更新,做想做的事。这是抽象基类。
 * 泛型V代表 表中 每一行数据对应的对象。
 */
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

public abstract class DBWorkerBase implements Runnable {
	private static final Logger logger = LoggerFactory
			.getLogger(DBWorkerBase.class);
	private static final ScheduledExecutorService ses = new ScheduledThreadPoolExecutor(
			10);

	// for the running task
	private int period;
	private ScheduledFuture future = null;
	/** 对应数据库中某张表的最后更新时间,由子类实现赋值 */
	private long lastTimestamp = -1;

	// used for the data storing
	private volatile List data = new ArrayList();
	/** 最近一次从数据库获取新数据的时间 */
	private volatile long lastFetchTimestamp = 0;
	/** run()执行后有没有得到已经变化的新数据 ,供子类使用*/
	protected boolean doesUpdateinMethodRUN = false;

	public DBWorkerBase(int periodBySecond) {
		this.period = periodBySecond;
	}

	/**
	 * Start the worker.
	 */
	public void start() {
		if (isStarted()) {
			return;
		}
		// 立即执行,然后每隔period执行一次
		future = ses.scheduleWithFixedDelay(this, 0, period, TimeUnit.SECONDS);
	}

	/**
	 * Stop the worker.
	 */
	public void stop() {
		if (isStarted()) {
			future.cancel(true);
			future = null;
		}
	}

	private boolean isStarted() {
		if (future == null) {
			return false;
		}
		if (future.isDone()) {
			future = null;
			return false;
		}
		return true;
	}

	@Override
	public void run() {
		doesUpdateinMethodRUN = false;
		// check if we need update
		long diff = System.currentTimeMillis() - lastFetchTimestamp;
		// 检查表的时间戳是否有变
		if (!checkUpdate()) {
			return;
		}
		doesUpdateinMethodRUN = true;
		try {
			data = doTask();
			lastFetchTimestamp = System.currentTimeMillis();
		} catch (Exception e) {
			logger.error("fail to do the task", e);
			return;
		}

	}

	protected abstract long getLastTime() throws Exception;

	/**
	 * Check if we need to retrieve the data again.
	 * @return
	 */
	protected boolean checkUpdate() {
		long newTime = -1;
		try {
			newTime = getLastTime();
		} catch (Exception e) {
			logger.error("fail to get last and timestamp", e);
			return true;
		}

		boolean needUpdate = false;
		if ((newTime != lastTimestamp)) {
			// has changed
			needUpdate = true;
			// update the timestamp
			this.lastTimestamp = newTime;
		}
		return needUpdate;
	}

	/**
	 * Every DB worker needs to implement the doTask to get the data from db.
	 * @return
	 */
	protected abstract List doTask() throws Exception;
	
	public List getData() {
		return data;
	}

}
/**
 * 定期检查Student表中的数据是否有变,若有更新,做想做的事。这是子类。
 */
import java.util.ArrayList;
import java.util.List;

public class StudentWorker extends DBWorkerBase {
	private DatasourceDAOImpl dao = new DatasourceDAOImpl();

	public StudentWorker(int period) {
		super(period);
	}

	@Override
	public void run() {
		super.run();
		// 若果得到了新数据,更新拼凑的EPL对应的数据库
		if (doesUpdateinMethodRUN) {
			// 自己想做的事
		}
	}

	@Override
	public List doTask() throws Exception {
		return dao.getStudents(null);
	}

	@Override
	protected long getLastTime() throws Exception {
		return dao.getLastModifiedTime().getTime();
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值