Windows 运行java定时器重复执行问题

发生个很古怪的现象

现在我有一个java程序,使用Springboot框架,程序中有很多使用 @Scheduled 注解的定时器,其中有一个定时器是一分钟执行一次(如下),并且执行开始和结束都会打印相应的日志信息记录,而程序运行在windows系统上的,并且保持开机自启,windows长时间保持运行状态。

    @Scheduled(fixedRate = 1 * 60 * 1000) //一分钟
    public void executeTask() {
        // 定时清除上报集合数据
        log.info("Periodically clear the reported collection data,reportTag size:{},reportImage size:{},reportNoread size:{}", reportTag.size(), reportImage.size(), reportNoread.size());
        // 这里是执行的任务逻辑
        log.info("Periodically clear the reported collection data completed,reportTag size:{},reportImage size:{},reportNoread size:{}", reportTag.size(), reportImage.size(), reportNoread.size());
    }

现在呢,由于windows设置可能有问题,导致可能一段时间未操作,导致系统进入了低功耗模式(不知道是休眠还是睡眠)(查询系统日志看到的),然后断电上电重启了windows系统,系统从低功耗模式恢复(系统日志显示),然后程序也会接着运行(程序日志显示程序未重新启动,而是接着上次的执行),这时候看日志发现,这个定时器记录的日志在几十毫秒内记录了几百上千条(一次执行记录两条)。

# 部分日志信息
14:34:05.669 [my-scheduler-4] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
14:34:05.669 [my-scheduler-4] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0

根据观察,每次发现处于低功耗后重启系统,定时器执行后日志的条数,随着低功耗时间的越长而记录的越多。
说明定时器可能是会补充执行低功耗期间未执行的任务的。

首先已经排除了其他原因,因为该程序已经在多个设备上长时间运行正常,且保持程序版本一致,配置一致,系统一致。
而且其他设备上的 Windows 系统设置上不存在系统长时间不操作后处于低功耗这个问题。

观察两天这个异常

我还发现了一个可以论证这个结论的定时器执行日志。
程序中其他部分也有很多定时器,但是很多没有记录日志,但是有一个定时有日志记录,且这个定时器一天执行一次,并且只在凌晨执行一次。

/**
     * 在每天的凌晨0点执行任务
     * 输出当天的航班统计数据
     * 并在输出后清空map
     */
    @Scheduled(cron = "0 0 0 * * ?")
    public void performTask() {
        log.info("Output flight statistics for the day !!!");
        // 下面是执行的任务
    }

这个定时器本该在凌晨0点时间执行一次,但是由于系统休眠未能执行,但是却在重启系统,系统从低功耗中恢复后,开始执行了一次,相当于补充执行了凌晨低功耗时间没有执行的这个任务。

# 以下是重新启动windows时,程序的部分日志
09:35:37.403 [my-scheduler-15] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:1,reportImage size:1,reportNoread size:2
09:35:37.403 [my-scheduler-10] INFO  com.eternal.ynan.YNanRFIDServer - heartBeat, data: {"statusFlag":"3","antnumStatus":"0,0,0,0"}
09:35:37.403 [my-scheduler-8] INFO  com.eternal.ynan.YNanBSMServer - Output flight statistics for the day !!!
09:35:37.403 [my-scheduler-15] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data,reportTag size:0,reportImage size:0,reportNoread size:0
09:35:37.403 [my-scheduler-15] INFO  com.eternal.ynan.YNanRFIDServer - Periodically clear the reported collection data completed,reportTag size:0,reportImage size:0,reportNoread size:0

解决办法

禁用 Windows 低功耗

最快的方法当然就是禁用系统的休眠和睡眠模式,防止长时间未操作进入低功耗模式。
要永久关闭 Windows 系统的低功耗模式(包括睡眠和休眠模式),可以通过以下几种方法进行设置:

方法一:通过控制面板关闭睡眠和休眠模式

  1. 打开控制面板
    • Win + R 键,输入 control 并按回车,打开控制面板。
  2. 进入电源选项
    • 在控制面板中,选择“系统和安全”。
    • 点击“电源选项”。
  3. 修改电源计划设置
    • 在当前使用的电源计划旁边,点击“更改计划设置”。
    • 设置“使计算机进入睡眠状态”选项为“从不”。
  4. 高级电源设置
    • 点击“更改高级电源设置”。
    • 在弹出的窗口中,展开“睡眠”选项。
    • 将“睡眠后”和“休眠后”都设置为“从不”。
    • 点击“确定”保存更改。

方法二:通过 Windows 设置应用关闭睡眠模式

  1. 打开设置
    • Win + I 键打开设置应用。
  2. 进入系统设置
    • 选择“系统”。
  3. 进入电源和睡眠设置
    • 选择左侧的“电源和睡眠”。
    • 在右侧窗口中,将“在使用电池时”和“插入电源时”的“PC 进入睡眠状态”选项都设置为“从不”。

方法三:通过命令提示符禁用休眠模式

  1. 打开命令提示符
    • Win + R 键,输入 cmd 并按回车。
  2. 输入禁用休眠模式的命令
    • 在命令提示符中输入以下命令并按回车:
powercfg -h off
  • 这将禁用系统的休眠模式,并删除 hiberfil.sys 文件,从而释放硬盘空间。

方法四:编辑组策略(适用于专业版和企业版)

  1. 打开组策略编辑器
    • Win + R 键,输入 gpedit.msc 并按回车。
  2. 导航到电源管理设置
    • 在组策略编辑器中,导航到 计算机配置 > 管理模板 > 系统 > 电源管理 > 睡眠设置
  3. 禁用睡眠
    • 双击“睡眠状态”设置,将其设置为“已禁用”。
  4. 禁用混合睡眠
    • 返回到“电源管理”下,找到“混合睡眠策略”,双击并将其设置为“已禁用”。

通过这些方法,您可以永久关闭 Windows 系统的低功耗模式,确保计算机不会进入睡眠或休眠状态。

使用 Linux 系统(推荐)

一般来说,用作服务器使用的系统,都尽量使用 Linux 系统。
尽量避免使用 windows 系统,防止出现一些奇奇怪怪的问题。

  • 16
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在Python中,你可以使用`time`模块来实现定时器重复执行。 以下是一个简单的示例代码,它将每隔一秒钟打印一次当前时间,重复执行10次: ```python import time def repeat_func(): for i in range(10): print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) time.sleep(1) repeat_func() ``` 如果你希望函数可以无限重复执行,可以使用`while`循环来实现: ```python import time def repeat_func(): while True: print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) time.sleep(1) repeat_func() ``` 注意,这个代码将无限循环执行,直到你手动停止程序。所以请确保你真的需要无限循环执行这个函数。 ### 回答2: 在Python中,可以通过使用内置的`time`模块配合`threading`模块来实现定时器重复执行的功能。具体步骤如下: 1. 首先,导入`time`和`threading`模块:`import time, threading` 2. 创建一个函数,作为定时器执行的任务。例如,我们可以创建一个名为`task`的函数。 3. 在`task`函数中编写需要定时执行的代码。 4. 创建一个无限循环,通过`time.sleep`方法来实现定时器重复执行。例如,如果希望任务每隔5秒执行一次,可以使用`time.sleep(5)`。 5. 在主程序中,使用`threading.Timer`方法创建一个定时器对象,并设置定时器触发的时间间隔和要执行的任务。 6. 调用定时器对象的`start`方法启动定时器。 以下是一个示例代码: ```python import time import threading # 定时器执行的任务 def task(): # 在这里编写需要定时执行的代码 print("执行任务...") # 模拟任务执行耗时 time.sleep(1) # 重复执行任务 timer = threading.Timer(5, task) timer.start() # 启动定时器 timer = threading.Timer(5, task) timer.start() # 主线程继续执行其他代码 print("主线程继续执行其他任务...") ``` 在上面的示例代码中,`task`函数中的代码会每隔5秒执行一次。我们可以根据实际需求修改定时器触发的时间间隔。另外,`task`函数中的代码可以是需要循环执行的任务,也可以是只执行一次的任务。 ### 回答3: 在Python中,我们可以使用`time`模块中的`sleep`和`Thread`模块中的`Timer`类来实现定时器重复执行。 首先,我们需要导入相关的模块: ```python import time from threading import Timer ``` 然后,在程序中定义一个函数,用于定时执行的任务: ```python def task(): # 这里可以写需要定时执行的任务 print("定时器任务执行中...") ``` 接下来,我们可以使用`time`模块的`sleep`方法来实现定时器重复执行。下面的代码演示了每隔一定时间执行一次任务的方式: ```python while True: task() # 执行任务 time.sleep(10) # 间隔10秒钟 ``` 上面的代码会无限循环执行任务,并每个任务之间休眠10秒钟。 另一种实现方式是使用`Thread`模块中的`Timer`类,可以设置定时器重复执行次数。下面的代码演示了每隔一定时间执行一次任务,并设置执行10次的方式: ```python def repeat_task(): task() # 执行任务 global repeat_count repeat_count -= 1 # 执行次数减1 if repeat_count > 0: t = Timer(10, repeat_task) # 创建一个定时器,间隔10秒钟执行 t.start() repeat_count = 10 t = Timer(0, repeat_task) # 创建一个定时器,立即执行任务 t.start() ``` 上面的代码会在启动后立即执行一次任务,然后每隔10秒钟重复执行一次任务,总共执行10次。 以上就是在Python中实现定时器重复执行的两种方法。你可以根据具体需求选择适合的方法来实现定时器重复执行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值