1.线程池中有哪些常见的阻塞队列
ArrayBlockingQueue:基于数组结构的有界阻塞队列
强制有界
底层是数组
提前初始化Node数组
Node需要是提前创建好
一把锁
LinkedBlockingQueue:基于链表结构的有界阻塞队列
默认无界,支持有界
底层是链表
是懒惰的,创建节点时候添加数据
入队会生成新的Node
两把锁(头和尾)
2.如何确定核心线程数
(1)高并发、任务执行时间短,CPU密集型任务,核心线程数=CPU核数+1,减少现场之间的切换
(2)并发不高、任务执行时间长
IO密集型任务:CPU核数*2+1(如文件读写,DB读写,网络请求)
计算密集型任务:CPU核数+1(如计算型代码,算法计算,Bitmap转换,Json转换)
(3)并发高、业务执行时间长,解决此类型任务不在于线程池而在于整体架构的设计,看看业务中某些数据是否能做到缓存是第一步,增加服务器是第二步,线程池设置参考2
3.线程池的种类有哪些
(1)固定大小的线程池newFixedThreadPool:创建一个定长的线程池,可控制线程最大并发数,超出的线程会在队列中等待
(2)单例的线程池newSingleThreadExecutor:创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO)执行
(3)可缓存线程池newCachedThreadPool:创建一个可缓存的线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若不可回收,则创建新的线程
(4)newScheduledThreadPool:可以执行延迟任务的线程池,支持定时或周期性线程执行
4.为什么不建议用Executors创建线程池
而通过ThreadPoolExecutor的方式
(1)FixedThreadPool和SingleThreadPool允许的请求队列长度为Integer.MAX_VALUE,可能会堆积大量的请求,导致内存溢出
(2)CachedThreadPool:
允许的创建线程数量为Integer.MAX_VALUE,可能会创建大量的线程,导致内存溢出