这个问题,很多人是通过修改tomcat的配置文件来解决的。这里之所以要提出一种直接解决方案,是应为并不是每个开发人员都有权限修改线上环境的tomcat配置,这个直接解决方案就是给无权修改tomcat配置的人或者想以直观的方式解决该问题的人准备的。
问题:通过@Scheduled配置定时任务,发现每到执行时间点,任务都会被执行两次。
解决思路:使用System.out.println(Thread.currentThread())打印出线程信息,发现每次都是两个不同线程再调用该任务。那么最直接的方法就是只让一个线程执行成功。
解决方案:通过原子类 AtomicLong 记录当前日期,如果当前日期没有被设置过,说明当前没有调用过改方法,如果设置过,则说明都不做。
代码:
@Component
@EnableScheduling
public class ScheduledJobs {
static AtomicLong atomicInteger = new AtomicLong();
@Autowired
SubscribeAndBindCardService subscribeAndBindCardService;
/**
* 每天凌晨1点统计前一天粉丝数据
*/
@Scheduled(cron = "0 0 1 * * ?")
private void makeSubscribeAndBindCardData() {
// 这里的atomicInteger 是为了解决 该定时任务每次调用都执行两次的问题。
long currentDate = LocalDate.now().toEpochDay();
if (atomicInteger.getAndSet(currentDate) != currentDate) {
System.out.println(Thread.currentThread());
System.out.println("LocalDate.now() = " + LocalDate.now());
try {
// 统计前一天的数据
LocalDate statDate = LocalDate.now().minusDays(1);
subscribeAndBindCardService.makeData(statDate, statDate);
} catch (Exception exception) {
exception.printStackTrace();
}
}
}
}