十一 线程池的使用场景
你们项目哪里用到了多线程
- 批量导入:使用了线程池+CountDownLatch批量把数据库中的数据导入到了ES(任意)中,避免OOM
- 数据汇总:调用多个接口来汇总数据,如果所有接口(或部分接口)的没有依赖关系,就可以使用线程池+future来提升性能
- 异步线程(线程池):为了避免下一级方法影响上一级方法(性能考虑),可使用异步线程调用下一个方法(不需要下一级方法返回值),可以提升方法响应时间
11.1 批量导入CountDownLatch
模拟案例1:
变成0在运行await之后的代码
真实案例:
es索引库
线程池:
逻辑代码
11.2 多线程使用场景二(数据汇总) Future
在一个电商网站中,用户下单之后,需要查询数据,数据包含了三部分:订单信息、包含的商品、物流信息;这三块信息都在不同的微服务中进行实现的,我们如何完成这个业务呢?
二。 future 获取结果(结果的返回值Map和定义的Map类型保持一致),get拿到方法,并行化汇总
11.3 异步线程调用 @Async
(保存搜索框的历史记录不能影响搜索功能,开一个线程执行,关键使用@Async(线程池))
关键字keyword 搜索文章数据
es索引库 app_info_article
关键字不为空,则执行insert方法保存搜索历史(关键方法)
@EnableAsync 开启异步调用,使@Async生效
表名异步调用方法 insert 中的@Async(线程池)
11.4 如何控制某个方法允许并发访问线程的数量 Semaphore
Semaphore['sema for]信号量,是JUC包下的一个工具类,底层是AQS,我们可以通过其限制执行的线程数量使用场景:
通常用于那些资源有明确访问数量限制的场景,常用于限流
在多线程中提供了一个工具类Semaphore,信号量。在并发的情况下,可以控制方法的访问量
- 1.创建Semaphore对象,可以给一个容量1.
- 2. acquire()可以请求一个信号量,这时候的信号量个数-1
- release()释放一个信号量,此时信号量个数+1
11.5 解决线程安全ThreadLocal
概述
ThreadLocal是多线程中对于解决线程安全的一个操作类,它会为每个线程都分配一个独立的线程副本从而解决了变量并发访问冲突的问题。ThreadLocal 同时实现了线程内的资源共享
案例:使用JDBC操作数据库时,会将每一个线程的Connection放入各自的ThreadLocal中,从而保证每个线程都在各自的 Connection 上进行数据库的操作,避免A线程关闭了B线程的连接。
原理
内存泄漏问题:
Java对象中的四种引用类型:强引用、软引用、弱引用、虚引用
强引用:最为普通的引用方式,表示一个对象处于有用且必须的状态,如果一个对象具有强引用,则GC并不会回收它。即便堆中内存不足了,宁可出现OOM,也不会对其进行回收
User user = new User();
弱引用:一旦发现弱引用,就会回收到弱引用:表示一个对象处于可能有用且非必须的状态。在GC线程扫描内存区域时,相关联的对象。对于弱引用的回收,无关内存区域是否足够,一旦发现则会被回收
User user = new User();
WeakReference weakReference = new WeakReference(user)