1、CachedThreadPool为什么会发生OOM异常?
创建了太多线程,内存溢出
2、如果一个任务要添加到线程池,处理流程是什么样的?
先判断任务阻塞队列是否满了,如果满了就看是实现了哪种拒绝策略,如果没满,则添加到任务阻塞队列中,线程集
合去判断是否任务数量大于核心线程数,大于就创建队列,最大不超过最大线程数,小于且线程超过空闲时间就减少
线程数量到核心线程数。
3、说说线程池的拒绝策略
第一种:直接抛弃新任务
第二种:直接抛弃新任务,抛出异常
第三种:抛弃最老的任务,添加新任务
第四种:直接使用当前线程执行任务
4、线程池有些什么核心属性?
核心线程数、最大线程数、线程空闲时间、阻塞队列、拒绝策略等
5、四种JDK提供的线程池是什么样的?
第一种:单个线程的线程池(newSingleThreadExecutor),单例模式,线程出现异常了重新创建线程
第二种:固定线程数的线程池(newFixedThreadPool)
第三种:可定时的线程池(newScheduledThreadPool),可以执行延迟任务,可以执行有返回值的任务
6、JDK提供的这几个线程池有什么问题?
固定线程数的线程池和单个线程的线程池会可能会堆积大量任务,造成OOM
缓存的线程池和可定时的线程池可能的创建大量线程,造成OOM
第四种:缓存的线程池(newCachedThreadPool)
7、线程池大小如何设计?
这个要看任务类型是CPU密集型的还是IO密集型的了,如果是CPU密集型就设置为CPU核数+1个线程,如果
是IO密集型,因为IO操作不占用CPU,所以可以设置为两倍的CPU+1个线程数量。
8、线程池底层是怎么实现的知道么?用的什么数据结构?
9、如果让你写一个线程池,你会怎么写,有哪些模块?
10、你线程池里怎么新建线程
11、如何手写一个简单的线程池?
(首先创建一个线程池类,里面有一些核心属性,比如核心线程数
最大线程数、任务阻塞队列、线程集合、线程空闲时间)
第一步:预热,通过构造函数创建核心线程并启动,还有就是创建阻塞队列 LinkedBolockingQueue
第二步:添加任务,创建一个execute方法,使用offer把任务添加到阻塞队列中
第三部:消耗任务,创建一个工作线程内部类,通过while循环不断调用poll方法
去获取任务,调用runnable的run方法执行任务。
12、为什么要使用线程池?
如果频繁的创建和销毁线程,对CPU消耗是很大的,需要考虑使用线程复用
13、使用线程池有什么优点?
复用线程,减少创建和销毁线程的CPU消耗还有就是统一管理线程