多线程的使用(springboot)
预备知识
业务使用多线程的原因
- 目的是面对高并发的时候,提高运行速度
场景一:
一个业务逻辑有很多次的循环,每次循环之间没有影响,比如验证1万条url路径是否存在,正常情况要循环1万次,逐个去验证每一条URL,这样效率会很低,假设验证一条需要1分钟,总共就需要1万分钟,有点恐怖。这时可以用多线程,将1万条URL分成50等份,开50个线程,没个线程只需验证200条,这样所有的线程执行完是远小于1万分钟的。
场景二:
需要知道一个任务的执行进度,比如我们常看到的进度条,实现方式可以是在任务中加入一个整型属性变量(这样不同方法可以共享),任务执行一定程度就给变量值加1,另外开一个线程按时间间隔不断去访问这个变量,并反馈给用户。总之使用多线程就是为了充分利用cpu的资源,提高程序执行效率,当你发现一个业务逻辑执行效率特别低,耗时特别长,就可以考虑使用多线程。
问题:不过CPU执行哪个线程的时间和顺序是不确定的,即使设置了线程的优先级,因此使用多线程的风险也是比较大的,会出现很多预料不到的问题,一定要多熟悉概念,多构造不同的场景去测试才能够掌握!
项目中可以通过:
@Order()
设置运行的优先级,数字越小,级别越高
FutureTask介绍
参考: (101条消息) FutureTask详解_索码理的博客-CSDN博客_futuretask
线程池为什么要使用阻塞队列
阻塞队列可以保证任务队列中没有任务时阻塞获取任务的线程,使得线程进入wait 状态,释放 cpu 资源,当队列中有任务时才唤醒对应线程从队列中取出消息进行执行。
使得在线程不至于一直占用cpu资源。(线程执行完任务后通过循环再次从任务队列中取出任务进行执行,代码片段如:while (task != null || (task = getTask()) != null) {})。
不用阻塞队列也是可以的,不过实现起来比较麻烦而已,有好用的为啥不用呢
Spring线程池
介绍:
Spring 通过任务执行器(TaskExecutor)来实现多线程和并发编程,使用 ThreadPoolTaskExecutor 实现一个基于线程池的TaskExecutor,
还得需要使用 @EnableAsync 开启异步,并通过在需要的异步方法那里使用注解@Async声明是一个异步任务
Spring 已经实现的异常线程池:
- SimpleAsyncTaskExecutor:不是真的线程池,这个类不重用线程,每次调用都会创建一个新的线程。
- SyncTaskExecutor:这个类没有实现异步调用,只是一个同步操作。只适用于不需要多线程的地方
- ConcurrentTaskExecutor:Executor的适配类,不推荐使用。如果ThreadPoolTaskExecutor不满足要求时,才用考虑使用这个类
- SimpleThreadPoolTaskExecutor:是Quartz的 SimpleThreadPool 的类。线程池同时被quartz和非quartz使用,才需要使用此类
- ThreadPoolTaskExecutor :最常使用,推荐。 其实质是对 java.util.concurrent.ThreadPoolExecutor 的包装
同步使用
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
FutureTask<List> commentCallable = new FutureTask<>(GrouponRulesCallable);
Future<Map> submit = executor.submit(commentCallable);
Map map = submit.get();
异步的使用:
[(101条消息) SpringBoot实现多线程_喜欢前端的后端MelodyJerry的博客-CSDN博客_springboot实现多线程](https://blog.csdn.net/weixin_43438052/article/details/116108860#:~:text=SpringBoot实现 多线程 1 SpringBoot通过 任务执行器TaskExecutor 来实现多线程和并发编程。 2 使用,%40EnableAsync 开启对 异步任务 的支持,并通过在实际执行的Bean中的方法使用 %40Async注解 来声明这是一个 异步任务 。)
JUC 的线程池
并发下使用同步线程
具体代码参考: litemall示例代码
- 声明
private final static ArrayBlockingQueue<Runnable> WORK_QUEUE= new ArrayBlockingQueue<>(9);
// handler – 由于达到线程边界和队列容量而阻塞执行时使用的处理程序
private final static RejectedExecutionHandler HANDLER=new ThreadPoolExecutor.CallerRunsPolicy();
private static ThreadPoolExecutor executorService = new ThreadPoolExecutor(16, 16, 1000, TimeUnit.MILLISECONDS, WORK_QUEUE, HANDLER);
- 使用,通过 get() 方法获取他的返回值
// 商品属性
Callable<List> listCallable =()->goodsAttributeService.getGoodsAttributeList(litemallGoods.getGoodsSn());
// 商品规格
Callable<Object> specificationCallable =()-> specificationService.getGoodsSpecification(litemallGoods.getGoodsSn());
FutureTask<List> goodsAttributeListTask = new FutureTask<>(listCallable);
FutureTask<Object> objectCallableTask = new FutureTask<>(specificationCallable);
executorService.submit(goodsAttributeListTask);
executorService.submit(objectCallableTask);
多线程的使用(springboot)的更多相关文章
- SpringBoot:实现定时任务
一.定时任务实现的几种方式: Timer 这是java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务.使用这种方式可以让你的程序按照某一个频度执 ...
- springboot 多线程执行
一.springboot开线程执行异步任务 1.Spring通过任务执行器TaskExecutor,来实现多线程和并发编程,使用ThreadPoolTaskExecutor可实现一个基于线程池的Tas ...
- springboot下多线程开发注意事项
基于springboot的多线程程序开发过程中,由于本身也需要注入spring容器进行管理,才能发挥springboot的优势.所以这篇文字主要用来记录开发中两者结合时需要注意的一些事项. 第一步我们 ...
- 关于java基础、多线程、JavaWeb基础、数据库、SSM、Springboot技术汇总
作者 : Stanley 罗昊 本人自行总结,纯手打,有疑问请在评论区留言 [转载请注明出处和署名,谢谢!] 一.java基础 1.多态有哪些体现形式? 重写.重载 2. Overriding的是什么 ...
- 转载-SpringBoot结合线程池解决多线程问题实录;以及自己的总结
原文地址:https://blog.csdn.net/GFJ0814/article/details/92422245 看看这篇文章(继续学习):https://www.jianshu.com/p/3 ...
- SpringBoot Test 多线程报错:dataSource already closed
1:前言 最近在项目中使用多线程对大任务拆分处理时,进行数据库操作的时候报错了. 业务代码大概是这样的: @Service public calss TestServiceImpl implement ...
- SpringBoot中如何优雅的使用多线程
SpringBoot中如何优雅的使用多线程 当异步方法有返回值时,如何获取异步方法执行的返回结果呢?这时需要异步调用的方法带有返回值CompletableFuture
- SpringBoot 多线程
Spring通过任务执行器(TaskExecutor)来实现多线程和并发编程.使用ThreadPoolTaskExecutor可实现一个基于线程池的TaskExecutor.而实际开发中任务一般是非阻 ...
- SpringBoot几种定时任务的实现方式 和多线程执行任务
定时任务实现的几种方式: Timer:这是java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务.使用这种方式可以让你的程序按照某一个频度执行, ...
随机推荐
- 哈希-hash
一. 概念 1.引例 有线性表(1,75,324,43,1353,90,46,- ) 目的:查找值为90的元素 常见做法: 1.通过一维数组进行遍历查找 (依次比较)( O(n) ) 2.如果关键字 ...
- 前端-关于CORS跨域的解决方案,面向服务端
最近自己在写后台管理系统的时候,并没有采用jsp.freemaker.叶子等模板技术,而是由后端提供数据api,前端通过AJAX和JQuery来动态操作页面上的一些div.table元素,从而实现报表 ...
- 20170622日行一记之PHP函数
fread() 函数读取文件(可安全用于二进制文件) fread(file,length) 参数 描述 file 必需.规定要读取打开文件. length 必需.规定要读取的最大字节数. 该函数在读取 ...
- Java面试题(二)--MySQL
1 存储引擎 1.简单描述一个Mysql的内部结构? MySQL的基本架构示意图: 大体来说,MySQL可以分为server层和存储引擎层两部分. ① server层包括连接器.查询缓存.分析器.优化 ...
- AOP实现切入
6.AOP实现切入 AOP为Aspect Oriented Programming的缩写,意为:面向切面编程 通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术 AOP是OOP的延续,也 ...
- 关于mybatis-plus出现Not Found TableInfoCache. 的解决方法
查看自己的pom里面是不是导入了多个mybatis相关,若是的话就全部删去,然后添加如下代码段即可 <dependency> <groupId>com.baomidou< ...
- 《吐血整理》进阶系列教程-拿捏Fiddler抓包教程(10)-Fiddler如何设置捕获Firefox浏览器的Https会话
1.简介 经过上一篇对Fiddler的配置后,绝大多数的Https的会话,我们可以成功捕获抓取到,但是有些版本的Firefox浏览器仍然是捕获不到其的Https会话,需要我们更进一步的配置才能捕获到会 ...
- 4步教你学会使用Linux-Audit工具
摘要:简单来讲audit是Linux上的审计工具,可以用来记录和监控对文件.目录.系统资源的更改:Audit无法直接增强系统的安全性,但是它可以用于发现违反系统安全政策的行为. 本文分享自华为云社区& ...
- Excel 数学函数(三):RAND 和 RANDBETWEEN
Excel 主要有 RAND 和 RANDBETWEEN 这两个函数生成随机数.RAND 默认生成 0~1 的随机数:RANDBETWEEN 有两个参数:bottom 和 top,bottom 代表函 ...
- Spring源码-入门
一.测试类 public class Main { public static void main(String[] args) { ApplicationContext applicationCon ...