为什么需要线程池?
程序中如果使用Thread或者Runnable的方式创建这样不但没有办法很好的去管理所创建出来的线程,并且执行一次都需要创建一个线程,这样没有任何的资源复用。所以就有了线程池的概念,线程池中定义的线程或通过不断获取阻塞队列中的任务,来达到资源的复用。
ThreadPoolExecutor的参数
- 核心线程数
- 最大线程数量
- 非核心线程的最大存在时间
- Junit对应时间的单位
- BlockingQueue 对应线程池的阻塞队列
- 线程工厂
- 拒绝策略
对于内部而言有几个比较重要的属性
- CTL 高3位表示当前线程池的几种状态,低位表示线程池的线程数量
- minLock(锁对象,用于保证HashSet线程安全)
- HashSet(用来存储每个线程任务Workers)
了解ThreadPoolExecutor的实现原理
在我们向ThreadPoolExecutor提交任务的时候,它会去判断当前的线程数量是否小于核心线程数量,如果小于那么就创建线程。 如果当前的线程数量要大于或等于核心线程的数量,那么就进入阻塞队列等待任务线程的调用。如果入队失败那么可能就是队列已经满了 。在队列满的情况ThreadPoolExecutor就会去创建线程来处理,但是如果当前线程数量要大于等于最大线程数量那么就会拒绝请求。 在我们创建的线程它会在内部不断的take阻塞队列中的值,如果阻塞队列为空它就会被阻塞。在空闲的时候线程的数量就会逐渐恢复到核心线程的数量。