线程池带来的好处
- 降低资源的消耗:通过重复利用已经创建好的线程降低线程的创建和销毁带来的损耗。
- 提高响应速度:当线程池中的线程数没有超过线程池的最大上限时,有的线程处于等待分配任务的状态,当任务来时无需创建新的线程就能执行。
- 提高线程的可管理性:线程池会根据当前系统特点对池内的线程进行优化处理,减少创建和销毁线程带来的系统开销。无限的创建和销毁线程不仅消耗系统资源,还降低系统的稳定性,使用线程池进行统一分配。
线程池七大参数
1. int corePoolSize:[5] 核心线程数;线程池,创建好后就准备就绪的线程数量,就等待来接受异步任务去执行。
2. int maximumPoolSize:[200] 最大线程数;控制资源。
3. long keepAliveTime:存活时间。如果当前的线程数量大于core数量。 释放空闲的线程(maximumPoolSize-corePoolSize),只要线程空闲大于指定的keepAliveTime。
4. TimeUnit unit:时间单位。
5. BlockingQueue <Runnable> workQueue:阻塞队列。如果任务有很多,就会将目前多的任务放在队列里面。只要有线程空闲,就会去队列里面取出新的任务继续执行。
6. ThreadFactory threadFactory:线程的创建工厂。
7. RejectedExecutionHandler handler:如果队列满了,按照我们指定的拒绝策略拒绝执行任务。
线程池工作顺序
- 线程池创建,准备好core数量的核心线程,准备接受任务。
- core满了,就将再进来的任务放入阻塞队列中。空闲的core就会自己去阻塞队列获取任务执行。
- 阻塞队列满了,就直接开新线程执行,最大只能开到max指定的数量。
- max满了就用RejectedExecutionHandler拒绝任务。
- max都执行完成,有很多空闲线程。在指定的时间keepAliveTime以后,释放max-core这些线程。new LinkedBlockingQueue<>():默认是Integer的最大值,内存不够。
注意点
- Executors.defaultThreadFactory():默认的线程创建工厂。
- 阻塞队列。
- 拒绝策略:
AbortPolicy:直接丢弃任务,抛出异常,这是默认策略。
CallerRunsPolicy:只用调用者所在的线程来处理任务。
DiscardOldestPolicy:丢弃等待队列中最旧的任务,并执行当前任务。
DiscardPolicy:直接丢弃任务,也不抛出异常。