文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

项目中发现了一个新的玩意WebAsyncTask

2024-12-03 04:29

关注

絮叨

刚好在读项目代码的时候,发现了WebAsyncTask这个新玩意,给大家来科普科普,不是那么的深入,不喜勿喷!

 

SpringBoot中同异步调用的使用

异步请求的处理。除了异步请求,一般上我们用的比较多的应该是异步调用。通常在开发过程中,会遇到一个方法是和实际业务无关的,没有紧密性的。比如记录日志信息等业务。这个时候正常就是启一个新线程去做一些业务处理,让主线程异步的执行其他业务。

SprinBoot中@Async异步方法

异步的好处是,可以提高程序吞吐量,一个任务,让耗时的异步处理,并继续同步处理后面的任务,异步任务可以返回结果,拿到结果后可结合同步处理过程中的变量一起处理计算

具体的使用

在Spring中,基于@Async标注的方法,称之为异步方法;这些方法将在执行的时候,将会在独立的线程中被执行,调用者无需等待它的完成,即可继续其他的操作。

自定义线程池异步调用

配置@EnableAsync使@Async生效

  1. @SpringBootApplication 
  2. @EnableAsync 
  3. public class Application { 
  4.   
  5.  public static void main(String[] args) { 
  6.   SpringApplication.run(Application.class, args); 
  7.  } 
  8.   

自定义线程池

  1. @Component 
  2. @Scope  //单例 
  3. public class MyExecutePoll { 
  4.   
  5.     @Bean 
  6.     public Executor myAsyncPool() { 
  7.         ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); 
  8.         //核心线程池大小 
  9.         executor.setCorePoolSize(20); 
  10.         //最大线程数 
  11.         executor.setMaxPoolSize(40); 
  12.         //队列容量 
  13.         executor.setQueueCapacity(50); 
  14.         // 活跃时间 
  15.         executor.setKeepAliveSeconds(300); 
  16.         // 线程名字前缀 
  17.         executor.setThreadNamePrefix("MyExecutor-"); 
  18.         //设置线程池关闭的时候等待所有任务都完成再继续销毁其他的Bean,使异步线程的销毁优先于Redis等其他处理报错 
  19.         executor.setWaitForTasksToCompleteOnShutdown(true); 
  20.         //设置线程池中任务的等待时间,如果超过这个时候还没有销毁就强制销毁,以确保应用最后能够被关闭,而不是阻塞住 
  21.         executor.setAwaitTerminationSeconds(60); 
  22.         // setRejectedExecutionHandler:当pool已经达到max size的时候,如何处理新任务 
  23.         // CallerRunsPolicy:不在新线程中执行任务,而是由调用者所在的线程来执行 
  24.         executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); 
  25.         executor.initialize(); 
  26.         return executor; 
  27.     } 
  28.   

使用@Async

  1. @Async("myAsyncPool")   //@Async使用默认的线程 
  2. public Future doTask() throws Exception { 
  3.     //业务处理   使用Future返回异步调用结果 
  4.     return new AsyncResult<>("任务一完成"); 

在Spring中运用 Async注解 需要注意几点:

基于Spring实现异步请求

Spring可以通过Callable或者WebAsyncTask等方式实现异步请求, 我们来看看,这2种实现方式!

Callable

Callable是为了异步生成返回值提供基本的支持。简单来说就是一个请求进来,如果你使用了Callable,在没有得到返回数据之前,DispatcherServlet和所有Filter就会退出Servlet容器线程,但响应保持打开状态,一旦返回数据有了,这个DispatcherServlet就会被再次调用并且处理,以异步产生的方式,向请求端返回值。这么做的好处就是请求不会长时间占用服务连接池,提高服务器的吞吐量。

  1. @GetMapping("/callable"
  2.     public Callable testCallable() throws InterruptedException { 
  3.         log.info("主线程开始!"); 
  4.         Callable result = new Callable() { 
  5.  
  6.             @Override 
  7.             public String call() throws Exception { 
  8.                 log.info("副线程开始!"); 
  9.                 Thread.sleep(1000); 
  10.                 log.info("副线程结束!"); 
  11.                 return "SUCCESS"
  12.             } 
  13.  
  14.         }; 
  15.         log.info("主线程结束!"); 
  16.         return result; 
  17.     } 

输出结果

  1. 主线程开始! 
  2.  
  3. 主线程结束! 
  4.  
  5. 副线程开始! 
  6.  
  7. 副线程结束! 

WebAsyncTask

一个请求到服务上,是用的web容器的线程接收的

我们可以使用WebAsyncTask将这个请求分发给一个新的线程去执行,容器的线程可以去接收其他请求的处理。一旦WebAsyncTask返回数据有了,就会被再次调用并且处理,以异步产生的方式,向请求端返回值,但是其实我觉得前端的请求rt并不会说变短。

  1.  
  2.    @RequestMapping(method = RequestMethod.GET, value = "/aysncTask/{testId}"
  3.    @ResponseStatus(HttpStatus.OK) 
  4.    public WebAsyncTask aysncTask(@PathVariable("testId") String testId) { 
  5.        System.out.println(String.format("/aysncTask/%s 被调用 thread id is: %s", testId,Thread.currentThread().getName())); 
  6.        Callable callable = () -> { 
  7.            Thread.sleep(1000L); 
  8.            Response response = new Response(true,"异步执行成功"); 
  9.            System.out.println(String.format("/aysncTask/%s 被调用 thread id is: %s", testId,Thread.currentThread().getName())); 
  10.            return response; 
  11.        }; 
  12.        return new WebAsyncTask(callable); 
  13.    } 

控制台打印如下:在执行业务逻辑之前的线程和具体处理业务逻辑的线程不是同一个,达到了我们的目的。async-customize-1这个前缀是我们自定义的下边会说

  1. /aysncTask/12348567676 被调用 thread id is: http-nio-8084-exec-1 
  2. /aysncTask/12348567676 被调用 thread id is: async-customize-1 

其实WebAsyncTask比起Callable是有以下几个优点的

官方有这么一句话,截图给你:

如果我们需要超时处理的回调或者错误处理的回调,我们可以使用WebAsyncTask代替Callable

实际使用中,我并不建议直接使用Callable ,而是使用Spring提供的WebAsyncTask 代替,它包装了Callable,功能更强大些

总结

 

其实本文就是给大家科普下,一些异步的用法,不至于说看到人家这么用很蒙b,多线程的东西还是优点东西的,大家一起学习。

 

来源:六脉神剑的程序人生内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯