1、利用spring编写定时任务
@Component
@Configurable
@EnableScheduling //关键注解
public class TimerScheduler {
@Scheduled(cron = "0 0 0-23 * * ?") //时间表达式,每天整点执行
public void emailPushByCron(){
System.out.printIn(“定时任务”);
}
}
2、利用java类ScheduledExecutorService
@Component
public class TimerUtil {
Private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
@PostConstruct //项目启动便调用
public void PostConstruct() {
final Runnable beeper = new Runnable() {
public void run() {
System.out.println(“定时任务”);
}
};
scheduler.scheduleAtFixedRate(beeper, 10, 60 * 60, SECONDS);
}
}
3、Redis用于分布式锁
实现思想:
· 获取锁的时候,创建一个key值加锁,并使用expire命令为锁添加一个超时时间,超过该时间则自动释放锁,锁的value值为机器ip,通过此可以判断出锁是被谁创建的。
· 释放锁的时候,通过ip判断是不是该锁,若是该锁,则执行delete进行锁释放。
实例如下:
@Component
@Configurable
@EnableScheduling
public class TimerScheduler {
private static final String LOCK_SUCCESS = "OK";
private static final Long RELEASE_SUCCESS = 1L;
private static final long DEFAULT_EXPIRE = 20000;//超时时间 20s
@Autowired
RedisRepository redisRepository
private static Logger logger = LoggerFactory.getLogger(TimerScheduler.class);
@Scheduled(cron = "0 0 0-23 * * ?")
public void emailPushByCron() {
String ip = this.getAddressIp(); // 获取本机ip
String key = "lock-scheduler";
/**
* redisRepository.set(key, ip, nxxx, expx, time)
* key:我们使用key来当锁,保持整个项目是唯一的
* ip:value值,表明当前占用锁的是哪一台机器
* nxxx:我们填的是NX,即当key不存在时,我们进行set操作;若key已经存在,则不做任何操作
* expx:我们传的是PX,意思是我们要给这个key加一个过期的设置,具体时间由第五个参数决定
* time:过期时间
*/
String result = redisRepository.set(key, ip, "NX", "PX", DEFAULT_EXPIRE);
if (LOCK_SUCCESS.equals(result)) {// 拿到锁,拥有执行权限
try {
logger.info("start execute...");
System.out.println(“定时任务”);
logger.info("scheduler finished...");
} finally { // 释放锁
// 定义Lua脚本代码,确保操作是原子性的,获取锁对应的value值,检查是否与ip相等,如果相等则删除锁
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
// jedis.eval()方法,执行Lua脚本,使参数KEYS[1]赋值为key,ARGV[1]赋值为ip
Object unlockResult = redisRepository.eval(script, Collections.singletonList(key), Collections.singletonList(ip));
if (RELEASE_SUCCESS.equals(unlockResult)) {
logger.info("unlock success...");
} else {
logger.info("unlock failed...");
}
}
} else { // 没拿到锁
// 查看当前锁是被谁占用
String lockIp = redisRepository.get(key);
logger.info("scheduler lock ip : {}", lockIp);
}
}
//获取ip地址
private String getAddressIp() {
try {
InetAddress addr = InetAddress.getLocalHost();
String ip = addr.getHostAddress().toString(); // 获取本机ip
return ip;
} catch (Exception e) {
// TODO: handle exception
return null;
}
}