java实现定时任务的四种方式及其应用代码和基本概念-Timer/ScheduledExecutorService/SpringTask/Quartz

jdk实际上自带了两种简单定时任务类,但由于功能的局限性,通知不会应用到项目中,这里只做简单介绍

1.Timer类

1.1概念
java.util.Timer类
Timer可以调用java.util.TimerTask任务
可以使TimerTask按固定频率执行
功能单一,通常不用
1.2任务类
extends TimerTask

public class DemoTimerTask extends TimerTask {
    @Override
    public void run() {
        System.out.println("Timer task1" + new Date());
    }
}


1.3启动定时任务

我这里写在了controller,如果要自启动那么定义到main即可

@GetMapping("/timer")
public void timer() {
    TimerTask timerTask = new DemoTimerTask();
    Timer timer = new Timer();
    //指定任务首次执行延迟,执行频率,单位毫秒
    timer.schedule(timerTask, 5000, 10000);
}

 

1.4注意
在多线程情况下Timer运行TimerTask时,
只要其中之一的TimerTask抛出异常,那么所有的TimerTask都会中止
而ScheduledExecutorService解决了这一问题

 

2.ScheduledExecutorService

2.1概念
java.util.concurrent.ScheduledExecutorService
与Timer类似,也是java自带的定时任务类
区别Timer的地方在于,ScheduledExecutorService是基于线程池设计的,
每个任务都会分配到线程池中的一个线程去执行,并发执行,互不影响
2.2任务类
implements Runnable

public class DemoScheduledExecutorService implements Runnable {

    @Override
    public void run() {
        System.out.println("ScheduledExecutorService task1" + new Date());
    }
}
    @GetMapping("/scheduledExecutorService")
    public void scheduledExecutorService() {
        ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
        service.scheduleAtFixedRate(new DemoScheduledExecutorService(),5,10, TimeUnit.SECONDS);
    }


//参数说明
1.任务类对象
2.首次执行延迟
3.任务执行频率
4.时间单位TimeUnit

 

 

3.SpringTask

1.概念
spring3.x提供的定时任务类,简单好用
2.1开启springtask
如果是一般的spring项目,需要在spring配置文件中开启定时任务

<!--开启定时任务多线程执行-->
<task:executor id="executor" pool-size="5"/>
<task:scheduler id="scheduler" pool-size="10"/>
<task:annotation-driven executor="executor" scheduler="scheduler">
<!-- 配置定时任务 -->
<task:scheduled-tasks>
<task:scheduled ref="任务bean1.name" method="任务方法名1" cron="0 * * * * ?" /></task:scheduled-tasks>
<task:scheduled-tasks><task:scheduled ref="任务bean2.name" method="任务方法名2" cron="0 * * * * ?" />
</task:scheduled-tasks>

如果是springboot项目,在启动类上增加注解@EnableScheduling即完成配置,如果需要开启多线程,则要单独编写配置类

@EnableAsync注解表示开启异步执行

@Configuration
@EnableAsync
public class AsyncConfig {
    private int corePoolSize = 10;
    private int maxPoolSize = 200;
    private int queueCapacity = 10;
    @Bean
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.initialize();
        return executor;
    }
}


2.2任务类
开启springtask后,编写任务类就可以了,spring会自动去bean中扫描注解@Scheduled并标记为任务类

@Component
public class DemoSpringTask {

    @Scheduled(cron = "0/5 * * * * ?")
    public void demo() {
        System.out.println("SpringTask:" + new Date());
    }
}



 

4.Quartz

<!--         Quartz 定时任务-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-quartz</artifactId>
        </dependency>

@Component
public class DemoQuartzTask1 {
    public void soutDate() {
        System.out.println("DemoQuartzTask1:" + new Date());
    }

}

@Data
public class DemoQuartzTask2 extends QuartzJobBean {
    /**
     * 这种方式定义任务类可以传参
     */
    String name;

    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println(name + "DemoQuartzTask:" + new Date());
    }
}

    /**
     * MethodInvokingJobDetailFactoryBean
     * 指定任务类的bean和bean中的任务方法,但不能传参,适合应用于bean方式定义的任务类
     *
     * @return MethodInvokingJobDetailFactoryBean
     */
    @Bean
    MethodInvokingJobDetailFactoryBean methodInvokingJobDetailFactoryBean() {
        MethodInvokingJobDetailFactoryBean bean = new MethodInvokingJobDetailFactoryBean();
        bean.setTargetBeanName("demoQuartzTask1");
        bean.setTargetMethod("soutDate");
        return bean;
    }

    /**
     * JobDetailFactoryBean
     * 指定任务类,任务类必须是Job接口的实现类(QuartzJobBean就实现了Job接口)
     * 可以传参,通过JobDataMap
     *
     * @return JobDetailFactoryBean
     */
    @Bean
    JobDetailFactoryBean jobDetailFactoryBean() {
        JobDetailFactoryBean bean = new JobDetailFactoryBean();
        bean.setJobClass(DemoQuartzTask2.class);
        JobDataMap jobDataMap = new JobDataMap();
        jobDataMap.put("name", "这是我的名字");
        bean.setJobDataMap(jobDataMap);
        return bean;
    }

    /**
     * CronTriggerFactoryBean
     */
    @Bean
    CronTriggerFactoryBean cronTrigger() {
        CronTriggerFactoryBean bean = new CronTriggerFactoryBean();
        bean.setCronExpression("0/10 * * * * ?");
        bean.setJobDetail(jobDetailFactoryBean().getObject());
        return bean;
    }

    /**
     * SchedulerFactoryBean
     * setTriggers(Trigger... triggers)可变参数,可以给调度器传多个触发器,触发多个任务,调度器内部是线程池调用
     *
     * @return
     */
    @Bean
    SchedulerFactoryBean schedulerFactoryBean() {
        SchedulerFactoryBean bean = new SchedulerFactoryBean();
        bean.setTriggers(cronTrigger().getObject());
        return bean;
    }

 

### 如何使用 Keil5 烧录 Hex 文件 对于仅拥有已编译好的 hex 文件而无源文件的情况,在 Keil V5 平台上直接烧录 hex 文件至单片机(如华大单片机)需采取特定的方法,因为直接调用该平台进行此类操作不可行[^1]。 #### 设置 Output 路径 进入 Keil 的 output 设置界面,指定要烧录的 hex 文件的具体位置。确保在路径输入框中填写完整的 hex 文件名称并附带 `.hex` 扩展名;缺少此扩展名可能导致系统继续尝试烧录先前编译的结果而非所选的 hex 文件[^3]。 #### 配置 Flash 工具选项 针对不同类型的微控制器(MCU),可能还需调整 flash 下载工具的相关配置参数以匹配目标设备的要求。这一步骤通常涉及选择合适的编程算法以及设定通信接口等细节[^2]。 #### 启动下载过程 完成上述准备工作之后,可以通过点击调试窗口内的 “Download” 或者快捷菜单里的相应命令来启动实际的程序写入流程。如果一切顺利的话,软件会自动连接硬件并将选定的 hex 数据传输到 MCU 中存储起来[^4]。 ```python # Python 示例代码用于说明自动化脚本概念 (并非真实实现) def download_hex_to_mcu(hex_file_path, mcu_type): """ 自定义函数模拟将 HEX 文件下载到指定型号的 MCU 上 参数: hex_file_path -- 完整路径字符串指向待上传的 .hex 文件 mcu_type -- 字符串表示的目标单片机类型标识符 返回值: 成功则返回 True ,失败抛出异常信息 """ try: configure_output_settings(hex_file_path) # 设定输出设置 select_flash_tool(mcu_type) # 挑选适合的闪存工具 execute_download_command() # 发送下载指令 return True # 表明成功结束 except Exception as e: raise RuntimeError(f"Failed to upload {hex_file_path}: {e}") ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值