ry
ry
发布于 2023-11-23 / 79 阅读 / 0 评论 / 0 点赞

异步化

异步化

同步:一件事做完,再做另一件事。

异步:不用等一件事做完,就可以做另一件事,第一件事做好后发送通知

调用的服务处理能力有限,或是接口处理时长较长时,可以考虑使用异步化的操作。

业务流程分析

标准异步化的业务流程:

1、当用户进行耗时很长的操作时,点击提交后不需要在界面等待,只需要把任务保存到数据库中记录下来。

2、用户要执行新任务时:

a、任务提交成功:任务队列没有满

i、如果程序有多余的空闲线程,可以立即去做

ii、若所有线程都繁忙,放到等待队列中

b、任务提交失败:所有线程都在忙,且任务队列已满

i、可以直接拒绝任务,不再执行

ii、再程序闲的时候,将保存到数据库中的失败记录对应的任务重新执行

3、程序从任务队列中取出任务,依次执行。每完成一件事修改数据库任务状态。

4、用户可以查询任务的执行状态,或者在任务执行成功时得到通知

5、如果我们要执行的任务非常复杂,包含很多环节,要在每一个小任务完成时记录任务执行状态。

线程池

为什么需要线程池?

1、线程管理比较复杂,比如什么时候新增线程,什么时候减少空闲线程

2、任务存取比较复杂,比如什么时候接受任务,什么时候拒绝任务

线程池可以帮助管理线程

在Spring中,可以使用ThreadPoolTaskExecutor配合@Async来实现(不建议)。

在Java中,可以使用JUC(java.util.concurrent)并发编程包中的ThreadPoolExecutor来实现非常灵活的自定义线程池。

线程池参数:
public ThreadPoolExecutor(int corePoolSize, 
						  int maximumPoolSize, 
						  long keepAliveTime, 
						  TimeUnit unit, 
						  BlockingQueue<Runnable> workQueue, 				
						  ThreadFactory threadFactory, 
						  RejectedExecutionHandler handler)

corePoolSize(核心线程数=>正式员工):系统应该能同时工作的线程数。

maximumPoolSize(最大线程数=>最多员工):极限情况下线程池的线程数。

keepAliveTime(空闲线程存活时间):非核心线程空闲时长,超时释放。

unit:时长单位。

workQueue(工作队列):按顺序存放给线程执行的任务,阻塞队列,存在队列最大长度,不能无限大。

threadFactory(线程工厂):控制每个线程的生成,线程属性。

handler(拒绝策略):当任务队列满时,采取什么措施(抛异常、优先级、抛弃任务、自定义策略等等)。资源隔离策略(会员一个队列,非会员一个队列)。

线程池步骤:

先招满员工,再堆满任务队列,都满了就新增临时工,临时工满了就调用拒绝策略。

线程池参数设置:

任务分为计算密集型、IO密集型

计算密集型:corePoolSize吃CPU性能,设置为CPU核数+1(空余线程),让每个线程利用好CPU的核,线程之间不用频繁切换。

IO密集型:吃带宽、内存、硬盘读写资源,corePoolSize可以设置大一些,一般2n左右,建议IO能力为主。


评论