/*******************************************************************************
* Copyright (c) 2005, 2014 springside.github.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
*******************************************************************************/
package org.springside.examples.showcase.demos.schedule;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.apache.commons.lang3.Validate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.support.TaskUtils;
import org.springside.modules.utils.Threads;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
/**
* 用JDKScheduledThreadPoolExecutor定时执行的任务。
* 相比Spring的Task NameSpace配置方, 不需要反射調用,并强化了退出超时控制.
*
* @author calvin
*/
public class JdkTimerJob implements Runnable {
private int initialDelay = 0;
private int period = 0;
private int shutdownTimeout = Integer.MAX_VALUE;
private ScheduledExecutorService scheduledExecutorService;
@Autowired
private UserCountScanner userCountScanner;
@PostConstruct
public void start() throws Exception {
Validate.isTrue(period > 0);
// 任何异常不会中断schedule执行, 由Spring TaskUtils的LOG_AND_SUPPRESS_ERROR_HANDLER進行处理
Runnable task = TaskUtils.decorateTaskWithErrorHandler(this, null, true);
// 创建单线程的SechdulerExecutor,并用guava的ThreadFactoryBuilder设定生成线程的名称
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(new ThreadFactoryBuilder().setNameFormat(
"JdkTimerJob-%1$d").build());
// scheduleAtFixedRatefixRate() 固定任务两次启动之间的时间间隔.
// scheduleAtFixedDelay() 固定任务结束后到下一次启动间的时间间隔.
scheduledExecutorService.scheduleAtFixedRate(task, initialDelay, period, TimeUnit.SECONDS);
}
@PreDestroy
public void stop() {
Threads.normalShutdown(scheduledExecutorService, shutdownTimeout, TimeUnit.SECONDS);
}
/**
* 定时打印当前用户数到日志.
*/
@Override
public void run() {
userCountScanner.executeByJdk();
}
/**
* 设置任务初始启动延时时间.
*/
public void setInitialDelay(int initialDelay) {
this.initialDelay = initialDelay;
}
/**
* 设置任务间隔时间,单位秒.
*/
public void setPeriod(int period) {
this.period = period;
}
/**
* 设置normalShutdown的等待时间, 单位秒.
*/
public void setShutdownTimeout(int shutdownTimeout) {
this.shutdownTimeout = shutdownTimeout;
}
}