首页 > 其他分享 >异步任务与定时任务

异步任务与定时任务

时间:2023-09-24 17:44:40浏览次数:35  
标签:异步 ... hello 任务 线程 executor 定时 public HelloScheduled

 

1. 异步任务使用

  (1)创建线程池配置

@Configuration
@EnableAsync  //开启多线程
public class ThreadPoolConfig {
    @Bean("taskExecutor")
    public Executor asyncServiceExecutor(){
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //设置核心线程数
        executor.setCorePoolSize(5);
        //设置最大线程数
        executor.setMaxPoolSize(20);
        //配置队列大小
        executor.setQueueCapacity(Integer.MAX_VALUE);
        //设置线程活跃时间
        executor.setKeepAliveSeconds(60);
        //设置线程名称
        executor.setThreadNamePrefix("lewang");
        //等待所有线程执行完成后关闭线程池
        executor.setWaitForTasksToCompleteOnShutdown(true);
        //执行初始化
        executor.initialize();
        return executor;
    }

}

  (2)在查看文章时对更新操作使用异步

    /*
        文章详情
     */
    @PostMapping("/view/{id}")
    public Result findArticleById(@PathVariable("id") Long articleId){
        return articleService.findArticleById(articleId);
    }

    @Override
    public Result findArticleById(Long articleId) {
        /**
         * 1. 根据id查询文章信息
         * 2. 根据body id和categoryid去做关联查询
         */
        Article article = articleMapper.selectById(articleId);
        ArticleVo articleVo = copy(article, true, true,true,true);

        //查看完文章,需要新增阅读数,需要执行更新操作,更新时会加写锁,阻塞其他读操作,性能低
        //更新操作增加了此次接口的耗时,如果有问题就影响查看操作
        //这是可以使用线程池,把更新操作放到线程池中执行和主线程就不相关了
        String view_count = (String) redisTemplate.opsForHash().get("view_count", String.valueOf(articleId));
        if(view_count != null){
            articleVo.setViewCounts(Integer.parseInt(view_count));
        }
        threadService.updateArticleViewCount(articleMapper,article);
        return Result.success(articleVo);
    }

@Component
public class ThreadService {

    //期望此操作在线程池中执行,不会影响原有的主线程
    @Async("taskExecutor")  //在线程池中执行此任务
    public void updateArticleViewCount(ArticleMapper articleMapper, Article article) {
        try {
            int viewCounts = article.getViewCounts();
            Article articleUpdate = new Article();
            articleUpdate.setViewCounts(viewCounts+1);
            LambdaUpdateWrapper<Article> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(Article::getId,article.getId());
            //对id和viewCounts都进行判断,为了在多线程环境下,viewCounts不会被其他的线程已经修改过
            updateWrapper.eq(Article::getViewCounts,viewCounts);
            //update article set view_count = 100 where view_count=99 and id = 11
            articleMapper.update(articleUpdate,updateWrapper);
            Thread.sleep(5000);
            System.out.println("更新完成了...");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

 

2. 定时任务

@Slf4j
@Component
// @EnableAsync
 @EnableScheduling
public class HelloScheduled {

     @Scheduled(cron = "* * * * * ?")
     public void hello() {
         log.info("hello...");
         try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }

     }
}
2023-09-24 17:29:36.001  INFO 9512 --- [   scheduling-1] c.l.g.seckill.scheduled.HelloScheduled   : hello...
2023-09-24 17:29:40.014  INFO 9512 --- [   scheduling-1] c.l.g.seckill.scheduled.HelloScheduled   : hello...
2023-09-24 17:29:44.005  INFO 9512 --- [   scheduling-1] c.l.g.seckill.scheduled.HelloScheduled   : hello...
2023-09-24 17:29:48.015  INFO 9512 --- [   scheduling-1] c.l.g.seckill.scheduled.HelloScheduled   : hello...

定时任务默认时阻塞的,可以通过定时任务和异步结合的方式来解决定时任务阻塞的问题

@Slf4j
@Component
 @EnableAsync
 @EnableScheduling
public class HelloScheduled {
    /**
     *   定时任务不该阻塞。默认是阻塞的
     *      1)、可以让业务以异步的方式,自己提交到线程池
     *              CompletableFuture.runAsync(() -> {
     *         },execute);
     *
     *      2)、支持定时任务线程池;设置 TaskSchedulingProperties
     *        spring.task.scheduling.pool.size: 5
     *
     *      3)、让定时任务异步执行
     *          异步任务
     *
     *      解决:使用异步任务 + 定时任务来完成定时任务不阻塞的功能
     *
     */
    @Async
     @Scheduled(cron = "* * * * * ?")
     public void hello() {
         log.info("hello...");
         try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }

     }
}
2023-09-24 17:34:28.015  INFO 15092 --- [         task-3] c.l.g.seckill.scheduled.HelloScheduled   : hello...
2023-09-24 17:34:29.003  INFO 15092 --- [         task-4] c.l.g.seckill.scheduled.HelloScheduled   : hello...
2023-09-24 17:34:30.002  INFO 15092 --- [         task-5] c.l.g.seckill.scheduled.HelloScheduled   : hello...

 

标签:异步,...,hello,任务,线程,executor,定时,public,HelloScheduled
From: https://www.cnblogs.com/homle/p/17726303.html

相关文章

  • 异步编程基础
    使用async和await进行异步操作的基础知识,其中只会涉及自然异步操作,如HTTP请求、数据库指令、Web服务调用等。一、需要通过异步签名实现同步方法时,返回已完成的任务 如果在继承异步接口或者基类的同时又想同步实现该任务,便可能发生这样的情况。当需要异步接口的简单签名......
  • Hadoop是什么? Hadoop是一个由Apache开发的开源分布式计算框架,它能够处理大规模数据并
    Hadoop是什么?Hadoop是一个由Apache开发的开源分布式计算框架,它能够处理大规模数据并行处理任务,支持大规模数据存储和处理。Hadoop的核心组件包括分布式文件系统HDFS和分布式计算框架MapReduce,它们使得Hadoop可以在廉价的硬件上并行地处理大量数据。Hadoop还包括很多相关的项目和子......
  • 栈和堆的区别、FreeRTOS 中的任务栈
    栈和堆的区别、FreeRTOS中的任务栈01 堆和栈的概念堆功能堆是一块用于动态分配内存的区域,用于存储程序运行时动态创建的对象。堆的大小可以在程序运行时动态调整。特点堆的分配和释放是由程序员手动控制的。堆的分配和释放顺序的任意的,不需要遵循先进先出的原则......
  • JS 设置定时器与清除定时器
    在前端,一些功能的实现需要用到定时器:轮询、定时开关弹窗、秒表、定时跳转等。。一、设置定时器window提供两个方法实现:setTimeout、setIntervalsetInterval():使一段代码每过一段时间就执行一次,比如轮询setInterval(()=>{console.log('setInterval定时器')},1000)s......
  • RocketMQ发送消息之同步异步单向
    官网教程:https://rocketmq.apache.org/zh/docs/quickStart/01quickstart基于双主双从异步方式开启的前提下,在maven项目中引入下列依赖<dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-client</artifactId><version>4.9.1&l......
  • win11任务栏变成透明的教程
    win11任务栏变成透明的教程其实win11原版的任务栏以纯色为主,并且没有任何的透明效果,让桌面壁纸无法完美展示出来,非常难看,因此我们可以通过第三方软件的方式来将它透明化,下面就一起来看一下具体的教程吧。win11任务栏怎么透明方法一:1、首先右键桌面空白处打开右键菜单,选择“......
  • 第一课:PRC、智能定时器、IP FRR
    一,OSPF快速收敛有关技术点1,OSPF的快速收敛:为了提高路由的收敛速度而做的扩展特性,包括:PRC(部分路由计算)和智能定时器。2,OSPF故障恢复的快速收敛:例如通过OSPFIPFRR(快速重路由)实现备份链路的快速切换,也可以与BFD联动实现对故障的快速感知。二,PRC(部分路由计算)1,PRC的工作原理......
  • Hadoop是什么? Hadoop是一个由Apache开发的开源分布式计算框架,它能够处理大规模数据并
    Hadoop是什么?Hadoop是一个由Apache开发的开源分布式计算框架,它能够处理大规模数据并行处理任务,支持大规模数据存储和处理。Hadoop的核心组件包括分布式文件系统HDFS和分布式计算框架MapReduce,它们使得Hadoop可以在廉价的硬件上并行地处理大量数据。Hadoop还包括很多相关的项目和子......
  • STM32之定时器
    定时器前言需要了解的基本知识:频率(frequency):是单位时间内完成周期性变化的次数,是描述周期运动频繁程度的量,常用符号f或ν表示,单位为秒分之一,符号为s-1。赫兹(HZ):是国际单位制中频率的单位,它是每秒钟的周期性变动重复次数的计量。1MHz=1000kHz=1000000Hz。周......
  • 2. 串口发送数据任务——基于FPGA的串口发送数据实验
    1.串口发送数据任务任务要求:使用上一节课设计的串口发送模块,设计一个数据发送器,每10ms以115200的波特率发送一个比特,每次发送的数据比前一个数据大1(计数器)1.1设计思路模块化设计,使用上一节课设计好的发送模块1.2设计开始设计Uart_Byte_Tx(单字节发送)模块选择使用以......