1 为什么要用线程池
1.1 线程the more, the better?
1、线程在java中是一个对象,更是操作系统的资源,线程创建、销毁都需要时间。
如果创建时间+销毁时间>执行任务时间就很不合算。
2、Java对象占用堆内存,操作系统线程占用系统内存,根据JVM规范,一个线程默认最大栈
大小1M,这个栈空间是需要从系统内存中分配的。线程过多,会消耗很多的内存。
3、操作系统需要频繁切换线程上下文(大家都想被运行),影响性能。
线程使应用能够更加充分合理地协调利用CPU、内存、网络、I/O等系统资源.
线程的创建需要开辟虚拟机栈、本地方法栈、程序计数器等线程私有的内存空间;
在线程销毁时需要回收这些系统资源.
频繁地创建和销毁线程会浪费大量的系统资源,增加并发编程风险.
在服务器负载过大的时候,如何让新的线程等待或者友好地拒绝服务?
这些都是线程自身无法解决的;
所以需要通过线程池协调多个线程,并实现类似主次线程隔离、定时执行、周期执行等任务.
2 线程池的作用
● 利用线程池管理并复用线程、控制最大并发数等
既然使用了线程池就需要确保线程池是在复用的,每次new一个线程池出来可能比不用线程池还糟糕。如果没有直接声明线程池而是使用其他人提供的类库来获得一个线程池,请务必查看源码,以确认线程池的实例化方式和配置是符合预期的
● 实现任务线程队列缓存策略和拒绝机制
● 实现某些与时间相关的功能
如定时执行、周期执行等
● 隔离线程环境
比如,交易服务和搜索服务在同一台服务器上,分别开启两个线程池,交易线程的资源消耗明显要大;
因此,通过配置独立的线程池,将较慢的交易服务与搜索服务隔离开,避免各服务线程相互影响.
在开发中,合理地使用线程池能够带来3个好处
降低资源消耗 通过重复利用已创建的线程,降低创建和销毁线程造成的系统资源消耗
提高响应速度 当任务到达时,任务可以不需要等到线程创建就能立即执行
提高线程的可管理性 线程是稀缺资源,如果过多地创建,不仅会消耗系统资源,还会降低系统的稳定性,导致使用线程池可以进行统一分配、调优和监控。
3 概念
1、线程池管理器
用于创建并管理线程池,包括创建线程池,销毁线程池,添加新任务;
2、工作线程
线程池中线程,在没有任务时处于等待状态,可以循环的执行任务;
3、任务接口
每个任务必须实现的接口,以供工作线程调度任务的执行,它主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等;
4、任务队列
用于存放没有处理的任务。提供缓冲机制。.
原理示意图
4 线程池API
4.1 接口定义和实现类
.线程池相关类图