一、业务场景
最近在做项目时,遇到一个业务场景:由于手机浏览器直接加载大PDF文件可能会导致加载失败,因此当用户上传PDF文件到FastDFS的时候,需要将pdf原文件上传,并且按照pdf文件页数转化成对应的图片在上传到FastDFS上。因为PDF转图片是一个比较耗时的操作,因此需要用到异步任务。
二、分析
首先想到的就是主线程去执行上传pdf原文件的操作,然后再开启一个线程来进行PDF转图片并上传fastdfs的操作,pdf原文件上传成功后即返回给用户上传成功的标志。
如果每发起一次请求,开启一个线程,当并发请求多的时候会导致线程数量非常多。而线程是非常宝贵的资源,随着并发访问量的提升,会发生线程堆栈溢出,创建新线程失败等问题。因此可以考虑采用线程池的方式来避免这种问题。(小伙伴,有没有感觉很熟悉,是不是非常类似于网络编程中的BIO和伪异步IO)。
三、java中的线程池
首先先谈一谈为什么要用线程池?
其一,减少创建和销毁线程所消耗的资源。其二,就是将当前任务与主线程隔离,能实现和主线程的异步执行,需要注意的是,一味的开线程也不一定能提高性能,线程休眠也需要耗费内存资源,所以需要合理选择线程池的大小。
我们的任务(Task)提交的线程池之后,又是按照什么样的规则去运行的呢?
1、exector一个线程之后,如果线程池中的线程数未达到核心线程数,则会立