以前定时任务一直用Timer这个类,后来发现ScheduledThreadPoolExecutor功能更强大,我们先看个简单的示例,然后再看看API中的描述:
这个定时任务是我的项目中,每隔5分钟去检查设备的在线状态的。
public class CheckDeviceStateExcuter {
private static final Log log = LogFactory.getLog(CheckDeviceStateExcuter.class);
private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
private static DeviceDao deviceDao = new DeviceDaoImpl();
private static List<DeviceDTO> devices = new ArrayList<DeviceDTO>();
// invoke DLL method to get the details of device
static JoymindCommDLLLib instance = JoymindCommDLLLib.INSTANCE;
// check states
public static void checkStart() {
final Runnable checker = new Runnable() {
public void run() {
System.out.println("check");
devices = deviceDao.queryDevices();
for(DeviceDTO device : devices){
String ip = device.getIp();
String id = "auto_refresh_" + ip;
String iniPath = XmlOperationTool.PLAYLIST_TEMPFILE_FOLDER + id
+ ".ini";
int flag = instance.GetSysInfo(ip, iniPath);
if(flag == 1){
// get ini file
SystemInfoDTO info = null;
try {
info = FileOperationTool.parseIni(iniPath);
device.setMacAdd(info.getMacAddress());
device.setIp(info.getIp());
device.setGateway(info.getGateway());
device.setOnlineState("在线");
device.setBootTime(info.getBootTime());
device.setDeviceVersion(info.getVersion());
device.setAvailableSpace(info.getFreedisk());
device.setpNo(info.getpNo());
device.setWidth(info.getWidth());
device.setHeight(info.getHeight());
device.setStorage(info.getStorage());
device.setTime(info.getTime());
device.setPrgTotal(info.getPrgTotal());
device.setPrgIndex(info.getPrgIndex());
device.setStatusNo(info.getStatus());
if (info.getStorage().equals("1")) {
device.setStorageName("FLASH存储");
}
if (info.getStorage().equals("2")) {
device.setStorageName("RAM存储");
}
if (info.getStorage().equals("3")) {
device.setStorageName("SD卡存储");
}
device.setCurrentPlaylist("");
device.setCurrentTemplate("");
device.setLastCommunicateTime("");
device.setCurrentTransferFileName("");
device.setCurrentTransferSpeed("");
device.setCurrentPercentage("");
device.setVolume("");
device.setAutoBootTime("");
device.setAutoShutdownTime("");
device.setPlayingVideo("");
device.setProgramUpdateTime("");
device.setProgramUpdateState("");
} catch (IOException e1) {
if (log.isErrorEnabled()) {
log.error(e1.getMessage());
}
e1.printStackTrace();
}
boolean addFlag = deviceDao.updateDevice(device);
if (addFlag) {
if (log.isDebugEnabled()) {
log.debug("auto update device "+device.getName()+" successfully");
}
} else {
if (log.isErrorEnabled()) {
log.error("auto update device failed !!!");
}
}
}else{
deviceDao.updateDevice(ip, "离线");
if (log.isDebugEnabled()) {
log.debug("auto update device "+device.getName()+" statue offline");
}
}
}
}
};
// 此处的checker是一个线程,1表示启动延迟1个单位开始执行这个线程,然后每隔5分钟执行一次,单位是分钟
final ScheduledFuture<?> checkerHandle = scheduler.scheduleAtFixedRate(checker, 1, 5, TimeUnit.MINUTES);
// 这里注释的地方是取消这个定时任务的,是在3600天后停止,因为我这里是检查设备的,所以除非当程序退出才自动停止这个定时任务
/*
scheduler.schedule(new Runnable() {
public void run() {
checkerHandle.cancel(true);
}
}, 60 * 60, TimeUnit.DAYS);
*/
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
}
再看看API的具体信息,总之这是个非常实用的类
public class ScheduledThreadPoolExecutor extends ThreadPoolExecutor implements ScheduledExecutorService
ThreadPoolExecutor
,它可另行安排在给定的延迟后运行命令,或者定期执行命令。需要多个辅助线程时,或者要求ThreadPoolExecutor
具有额外的灵活性或功能时,此类要优于 Timer
。
一旦启用已延迟的任务就执行它,但是有关何时启用,启用后何时执行则没有任何实时保证。按照提交的先进先出 (FIFO) 顺序来启用那些被安排在同一执行时间的任务。
虽然此类继承自 ThreadPoolExecutor
,但是几个继承的调整方法对此类并无作用。特别是,因为它作为一个使用 corePoolSize 线程和一个无界队列的固定大小的池,所以调整maximumPoolSize 没有什么效果。
扩展注意事项:此类重写 AbstractExecutorService
的 submit 方法,以生成内部对象控制每个任务的延迟和调度。若要保留功能性,子类中任何进一步重写的这些方法都必须调用超类版本,超类版本有效地禁用附加任务的定制。但是,此类提供替代受保护的扩展方法decorateTask(为 Runnable 和 Callable 各提供一种版本),可定制用于通过 execute、submit、schedule、scheduleAtFixedRate 和 scheduleWithFixedDelay 进入的执行命令的具体任务类型。默认情况下,ScheduledThreadPoolExecutor 使用一个扩展FutureTask
的任务类型。但是,可以使用下列形式的子类修改或替换该类型。
public class CustomScheduledExecutor extends ScheduledThreadPoolExecutor { static class CustomTask<V> implements RunnableScheduledFuture<V> { ... } protected <V> RunnableScheduledFuture<V> decorateTask( Runnable r, RunnableScheduledFuture<V> task) { return new CustomTask<V>(r, task); } protected <V> RunnableScheduledFuture<V> decorateTask( Callable<V> c, RunnableScheduledFuture<V> task) { return new CustomTask<V>(c, task); } // ... add constructors, etc. }
-
从以下版本开始:
- 1.5