本来想说说检索的,不过不知道什么鬼,下载ElasticSearch太慢了,还是放一下,后面有机会再补上!今天就说个简单的东西,来说说任务。

  什么叫做任务呢?其实就是类中实现了一个什么功能的方法。常见的任务就是异步任务,定时任务,发邮件。

  异步任务:其实就是一个很特别的方法,这个方法没有返回值(也可以有返回值,后面会说的),但是方法内部的逻辑会耗费很多时间!例如,用户请求每次到controller,要执行到这个异步方法的时候,我们只需要命令一个空闲状态的线程去执行它即可,由于没有返回值不影响后续代码的运行,controller直接去执行后续的代码。这样可以极为迅速的响应用户,用户体验非常好。

  定时任务:这个其实看名字就知道了,你可以选定一个月的哪一天哪个小时的具体时分秒,去执行一个方法。这个方法是自动执行的,极大的减轻了我们的工作量。

  发邮件:这个还是比较常见的吧!注册什么的大多都要邮件激活,我们也可以用java程序的方式,来给你邮箱发邮件。

  提前准备:大概了解一下javase中多线程和线程池概念,重点是ThreadPoolTaskExecutor这个类。

1.简单说说异步任务和RabbitMQ

  不知道看了我上面说了异步任务,大家有没有想到前面说过的一个东西,就是RabbitMQ啊!这个消息队列,不就是也是这样的吗?生产者发消息给交换器之后,就不管了,也许生产者就可以直接响应用户响应成功了。而内部也许还有交换器发消息给队列,然后消费者消费消息,但这个过程就跟用户就没什么关系了,干嘛要用户浪费时间在那瞎等呢?

  就我而言,异步任务和RabbitMQ最大的区别应该是访问量的差异;可以将异步任务看作是简化版RabbitMQ 。

  你想啊,假如你做了一个系统,最大访问量总共那么点人,你还要去用个RabbitMQ去搞这搞那的,麻不麻烦啊。。。

  但是假如你在一家大公司,做的系统是给几十万甚至几百万用户用的,那么肯定要用RabbitMQ啊。这个时候如果用异步任务,哪有这么多空闲线程去给你执行这个任务啊,而且线程到了一个数目之后,效率反而是降低的。

  补充小知识:大家知不知道服务器怎么处理多个请求的啊?

  假如都是同步任务:请用请求一到,服务器就出用一个线程去执行,并且到了service层之后,假设会有个任务需要几十秒才能执行完毕;那么执行到这里就会卡住了,请求到这里都要卡住几十秒,人多的时候可能还要排队,等时间过了你才会得到响应。

  那就等着呗,然而不巧的是,这个时候又有几千人来来给服务器发请求,于是这几千人每人等几十秒,而且由于服务器又比较水,一下子开了几千个线程还有点卡于是要等更长时间。(咳,所以越贵的服务器配置高,线程能够开得多,运行速度快,处理多人请求的能力就很牛),于是这几千人用了这个系统之后,心中大骂日了狗了哦,下次再也不用这个鬼系统了。

  那假如是异步任务:还是用订单/库存系统举例,几千人都在买买买,一时间几千个订单请求到controller,然后调用service(注:service还是跟上面一样要几十秒),一到service,判断是个异步方法,于是赶紧让处理异步任务的线程过来慢慢处理就好,controller可以直接响应用户“订单成功”。用户极短时间就收到响应,于是可以继续买买买。

  这里就要说个东西,那个处理异步方法的线程哪里来的啊?其实是从异步方法线程池里拿的。大家应该知道连接池啊,是处理与数据库连接问题的,还能设置个数,最大超时时间等等,还能防止频繁的销毁创建线程的资源消耗。这里的线程池也差不多,可以设置个数啊什么的。。。。后面我们就会试试简单的配置一个连接池专门处理异步任务。

2.简单使用异步任务

  创建一个简单的springboot项目,web模块+1.5.xx版本。

  简单写个controller和一个处理逻辑的类,先看看同步处理:

  ok,你可以测试一下,等5秒钟浏览器才会响应,emmm...玛德,等得真烦。。。

  测试异步处理,加两个注解就ok了。

  然后这次就能不超过一秒钟,就返回响应成功了,你们也可以自己用System.currentTimeMillis()这个方法去测测时间,这里就不多说了。

  这里就需要考虑了,假如访问量很多,每个请求都过来调用HelloTask方法,那就要拿到相应数量的处理异步的线程,来处理这个HelloTask方法!

  处理异步任务的线程也是属于服务器的线程啊,线程数太多服务器会很卡的,默认是有线程池的!但是我们根据自己项目的需求,于是要自定义线程池的一些配置。

  假如线程池里就设置最多30个线程(这里也会有个类似RabbitMq的简单消息队列),那么即使几千人来调用HelloTask方法,那么最多也就拿到30个处理异步的线程,来处理这个方法;至于其他的那么多请求就丢到请求队列里,等这30个线程中某些率先处理完任务的线程就会从这消息队列中拿任务继续处理。

3.自定义异步任务的线程池

   刚刚查一下资料,其实也是可以用多线程来做的,只是每次都用多线程比较麻烦,不过小伙伴们可以试试。

  线程池就相当于包装了一下多线程的操作,做了很多配置!就类似ArrayList和Object数组的关系。

  

  在下面方法打印当前线程(注意,这里注解@Async(“自己配置的线程池的名字”),这里可以指定配置的哪个线程池,可以自己试试,我们这里要写应该是taskExecutor)

 然后运行,打开浏览器,疯狂刷新,控制台打印如下;(注意:可以把线程池中线程数目弄少一点,把sleep时间调整短一点,就能明显看到线程不会按顺序使用了,而是随机的!这个自己可以测试一下)

4.给异步方法设置返回值

   前面说的都是异步方法返回值为void的情况,但是有的时候我们要拿到异步方法的返回值。

  这个逻辑是怎么回事呢?有了返回值还能异步吗?答案是可以的。

  举个例子,当请求到controller,线程就会去执行controller方法,碰到了要执行一个异步方法,于是异步方法立马返回一个Future对象敷衍controller一下(玛德,controller真是老实人...),然后继续执行controller后面的方法,不会停顿;

  这个Future就是异步方法的返回值,只是刚开始还没有数据,等异步方法执行完毕,自动的就会将数据放入Future,比较常见的是利用Future来捕获异常。

  其中,Future是个接口,实现类是AsyncResult,下面就看看修改后的controller:

 

  再看看异步方法内部代码:

  ok,可以了,运行应用,测试结果如下:

  简单的看了看异步任务的用法,应该还是比较容易的,用起来也没什么难度,就是真实项目碰到的情况可能就会很复杂,要考虑的情况比较多了。

带着新人学springboot的应用09(springboot+异步任务)的更多相关文章

  1. 带着新人学springboot的应用01(springboot+mybatis+缓存 上)

    上一篇结束,第一次做一个这么长的系列,很多东西我也是没有说到,也许是还没有想到,哈哈哈,不过基本的东西还是说的差不多了的.假如以后碰到了不会的,随便查查资料配置一下就ok. 咳,还有大家如果把我前面的 ...

  2. 带着新人学springboot的应用04(springboot+mybatis+redis 完)

    对于缓存也说了比较多了,大家对下图这一堆配置类现在应该有些很粗略的认识了(因为我也就很粗略的认识了一下,哈哈!),咳,那么我们怎么切换这个缓存呢?(就是不用springboot提供的默认的Simple ...

  3. 带着新人学springboot的应用07(springboot+RabbitMQ 下)

    说一两句废话,强烈推荐各位小伙伴空闲时候也可以写写自己的博客!不管水平高低,不管写的怎么样,不要觉得写不好或者水平不够就不写了(咳,我以前就是这样的想法...自我反省!). 但是开始写博客之后,你会发 ...

  4. 带着新人学springboot的应用13(springboot+热部署)

    spring cloud我想做成一个系列,所以spring cloud+eureka后面会慢慢说到的,有兴趣的小伙伴可以关注后续! 这一节就简单说说springboot的热部署了(我一直想不通为什么叫 ...

  5. 带着新人学springboot的应用11(springboot+Dubbo+Zookeeper 上)

    这次说个在大型项目比较常见的东西,就是分布式,分布式到底是个什么东西呢?概念太大,不好说,就像刚学javaee的人问你,什么是web啊,什么是spring啊等等,你可能觉得,这个东西我好像知道,但是用 ...

  6. 带着新人学springboot的应用10(springboot+定时任务+发邮件)

    接上一节,环境一样,这次来说另外两个任务,一个是定时任务,一个是发邮件. 1.定时任务 定时任务可以设置精确到秒的准确时间去自动执行方法. 我要一个程序每一秒钟说一句:java小新人最帅 于是,我就写 ...

  7. 带着新人学springboot的应用08(springboot+jpa的整合)

    这一节的内容比较简单,是springboot和jpa的简单整合,jpa默认使用hibernate,所以本质就是springboot和hibernate的整合. 说实话,听别人都说spring data ...

  8. 带着新人学springboot的应用06(springboot+RabbitMQ 中)

    上一节说了这么多废话,看也看烦了,现在我们就来用鼠标点点点,来简单玩一下这个RabbitMQ. 注意:这一节还是不用敲什么代码,因为上一节我们设置了那个可视化工具,我们先用用可视化工具熟悉一下流程. ...

  9. 带着新人学springboot的应用05(springboot+RabbitMQ 上)

    这次就来说说RabbitMQ,这个应该不陌生了,随便一查就知道这个是用来做消息队列的.(注意:这一节很多都是概念的东西,需要操作的比较少) 至于AMQP协议(Advanced Message Queu ...

随机推荐

  1. 【redis】在windos下的redis服务器的搭建

    1.下载Redis-x64-3.2.100(楼主用的版本,需要安装包的可以找我要) 下载官方版本 2.解压后在cmd下运行 redis-server redis.windos.conf 此时redis ...

  2. Win10家庭版WindowsUpdate属性为灰色

    一般的取消Windows更新只需要打开任务管理器,点击服务 然后点击左下角的打开服务 找到WindowsUpdate,右键属性 按照正常的电脑只要在启动类型中选择禁用,然后在恢复里的第一次操作选择无操 ...

  3. js基础知识易错点(一)

    最近替另一个项目招人,要求基础知识好,随便问了一些基础题,发现了一些易错的点,总结一下. 1.判断一个空数组 var arr = []; 1)JSON.stringify(arr) == " ...

  4. 使用HttpClient发送文件流到服务器端

    适用场景:网络绝对路径的URL文件或图片,不存储到本地,转换成stream,直接使用HTTPClient传送到SpringBoot的服务端,将文件存储下来,并返回一个文件地址.目前分层架构的系统越来越 ...

  5. CF719E. Sasha and Array [线段树维护矩阵]

    CF719E. Sasha and Array 题意: 对长度为 n 的数列进行 m 次操作, 操作为: a[l..r] 每一项都加一个常数 C, 其中 0 ≤ C ≤ 10^9 求 F[a[l]]+ ...

  6. 基于.net的Socket异步编程总结

    最近在为公司的分布式服务框架做支持异步调用的开发,这种新特性的上线需要进行各种严格的测试.在并发性能测试时,性能一直非常差,而且非常的不稳定.经过不断的分析调优,发现Socket通信和多线程异步回调存 ...

  7. Vue 入门. 如何在HTML代码里面快速使用Vue

    概述 browserify是一个 CommonJS风格的模块管理和打包工具,上一篇我们简单地介绍了Vue.js官方基于browserify构筑的一套开发模板.webpack提供了和browserify ...

  8. 4.28Linux(6)

    2019-4-28 21:27:41 明天回家.回家继续学Linux还好有个服务器!!!感觉有个属于自己的服务器感觉好爽啊!! 越努力越幸运!永远不要高估自己!!! Nginx安装 服务器的请求原理 ...

  9. Golang Go Go Go part1:安装及运行

    golang 知识图谱 https://www.processon.com/view/link/5a9ba4c8e4b0a9d22eb3bdf0 一.安装 最新版本安装包地址:https://gola ...

  10. 【RL-TCPnet网络教程】第4章 RL-TCPnet网络协议栈简介

    第4章        RL-TCPnet网络协议栈简介 本章节介绍RL-TCPnet网络协议栈,让大家对 RL-TCPnet有一个整体的了解,RL-TCPnet是一款小型网络协议栈,适用于 ARM 内 ...